Skip to content

Commit

Permalink
Merge pull request #429 from ScorexFoundation/new-costing
Browse files Browse the repository at this point in the history
New costing
  • Loading branch information
catena2w authored Mar 14, 2019
2 parents 6efa97c + 9cc6610 commit 94cc64d
Show file tree
Hide file tree
Showing 145 changed files with 8,280 additions and 4,848 deletions.
8 changes: 4 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ val scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.1.3"
val macroCompat = "org.typelevel" %% "macro-compat" % "1.1.1"
val paradise = "org.scalamacros" %% "paradise" % "2.1.0" cross CrossVersion.full

val specialVersion = "master-518e9d01-SNAPSHOT"
val specialVersion = "master-5ffd1bf8-SNAPSHOT"
val specialCommon = "io.github.scalan" %% "common" % specialVersion
val specialCore = "io.github.scalan" %% "core" % specialVersion
val specialLibrary = "io.github.scalan" %% "library" % specialVersion
Expand Down Expand Up @@ -137,7 +137,7 @@ credentials ++= (for {

def libraryDefSettings = commonSettings ++ testSettings ++ Seq(
scalacOptions ++= Seq(
// s"-Xplugin:${file(".").absolutePath }/scalanizer/target/scala-2.12/scalanizer-assembly-eq-tests-cb1f5c15-SNAPSHOT.jar"
// s"-Xplugin:${file(".").absolutePath }/scalanizer/target/scala-2.12/scalanizer-assembly-better-costing-2a66ed5c-SNAPSHOT.jar"
)
)

Expand All @@ -151,8 +151,8 @@ lazy val scalanizer = Project("scalanizer", file("scalanizer"))
.dependsOn(sigmaconf)
.settings(commonSettings,
libraryDependencies ++= Seq(meta, plugin, libraryapi, libraryimpl),
publishArtifact in(Compile, packageBin) := false,
assemblyOption in assembly ~= { _.copy(includeScala = false, includeDependency = false) },
// publishArtifact in(Compile, packageBin) := false,
assemblyOption in assembly ~= { _.copy(includeScala = false, includeDependency = true) },
artifact in(Compile, assembly) := {
val art = (artifact in(Compile, assembly)).value
art.withClassifier(Some("assembly"))
Expand Down
2 changes: 1 addition & 1 deletion docs/TypeSerialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ x = 0xXX | `Byte` | `byte(x)` - one byte storing value x
b = false/true| `Boolean` | `if (b) byte(0x01) else byte(0x00)]` - one byte storing 0 or 1
n = 0xXXXXXXXXXXXXXXXX | `Int` | `[XX,XX,XX,XX,XX,XX,XX,XX]` - big endian 8 bytes
N = new BigInteger() | `BigInt` | xs = N.toByteArray, `[serialize(xs)]` - serialize as `Coll[Byte]`, see also BigInteger.toByteArray
e = new EcPoint() | `GroupElement` | `[e.getEncoded(true)]` see also org.bouncycastle.math.ec.EcPoint.getEncoded(true)
e = new EcPoint() | `GroupElement` | `[e.getEncoded]` see also use GroupElementSerializer
box = new ErgoBox() | `Box` | `[putLong(box.value), putValue(box.proposition), putArray[Any](box.registers), 32, putBytes(box.transactionId), putShort(box.boxId)]`
t = new AvlTree() | `AvlTree` | `[serialize(t.startingDigest), putInt(t.keyLength), putOpt(t.valueLengthOpt), putOpt(t.maxNumOperations), putOpt(t.maxDeletes)]`
xs = Coll(x1, .., xN) | `Coll[T]` | `[xs.length & 0xXXXX, serialize(x1), ..., serialize(xN)]` - 2 bytes of length and recursive bytes of all the elements
1 change: 1 addition & 0 deletions docs/conversions.dot
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ digraph conversions {
GroupElement -> SigmaProp [label="proveDlog(...)"]
GroupElement -> Boolean [label=".isIdentity"]
GroupElement -> Bytes [label=".nonce"]
//todo remove compressed flag, use GroupElementSerializer
GroupElement -> Bytes [label=".getEncoded(compressed)" color=red]

String -> Bytes [label="fromBase58(...)"]
Expand Down
13 changes: 13 additions & 0 deletions docs/sigma-dsl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Sigma: Scala DSL for smart contracts with zero knowledge proof of knowledge

## Intro
SigmaDsl is a domain-specific language embedded into Scala and designed to be
source code compatible with SigmaScript. This means you can write SigmaDsl
code directly in Scala IDE (e.g. IntelliJ IDEA) and copy-paste code snippets
between SigmaDsl and SigmaScript.

SigmaDsl is implemented as a library in the framework of
[Special](https://github.com/scalan/special)

## See also
[Special](https://github.com/scalan/special)
81 changes: 41 additions & 40 deletions sigma-api/src/main/resources/special/sigma/CostedObjects.scalan
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,50 @@ package special.sigma {
import Box._;
import Coll._;
import Context._;
import Costed._;
import CostedAvlTree._;
import CostedBox._;
import CostedBuilder._;
import CostedColl._;
import CostedOption._;
import CostedSigmaObject._;
import SigmaDslBuilder._;
trait CostedSigmaObject[Val] extends Costed[Val] {
implicit def eVal: Elem[Val];
def dsl: Rep[SigmaDslBuilder];
def builder: Rep[CostedBuilder] = CostedSigmaObject.this.dsl.Costing
import Header._;
import PreHeader._;
import SigmaProp._;
import Size._;
import SizeAnyValue._;
import SizeBox._;
import SizeBuilder._;
import SizeContext._;
import WOption._;
import WRType._;
@Liftable trait SizeAnyValue extends Size[AnyValue] {
def tVal: Rep[WRType[Any]];
def valueSize: Rep[Size[Any]]
};
trait CostedContext extends CostedSigmaObject[Context] {
def OUTPUTS: Rep[CostedColl[Box]];
def INPUTS: Rep[CostedColl[Box]];
def HEIGHT: Rep[Costed[Int]];
def SELF: Rep[CostedBox];
def LastBlockUtxoRootHash: Rep[CostedAvlTree];
def MinerPubKey: Rep[CostedColl[Byte]];
def getVar[T](id: Rep[Byte])(implicit cT: Elem[T]): Rep[CostedOption[T]];
def getConstant[T](id: Rep[Byte])(implicit cT: Elem[T]): Rep[Costed[T]]
@Liftable trait SizeSigmaProp extends Size[SigmaProp] {
def propBytes: Rep[Size[Coll[Byte]]]
};
trait CostedBox extends CostedSigmaObject[Box] {
def id: Rep[CostedColl[Byte]];
def valueCosted: Rep[Costed[Long]];
def bytes: Rep[CostedColl[Byte]];
def bytesWithoutRef: Rep[CostedColl[Byte]];
def propositionBytes: Rep[CostedColl[Byte]];
def registers: Rep[CostedColl[AnyValue]];
def getReg[T](id: Rep[Int])(implicit cT: Elem[T]): Rep[CostedOption[T]];
def creationInfo: Rep[Costed[scala.Tuple2[Int, Coll[Byte]]]]
@Liftable trait SizeBox extends Size[Box] {
def propositionBytes: Rep[Size[Coll[Byte]]];
def bytes: Rep[Size[Coll[Byte]]];
def bytesWithoutRef: Rep[Size[Coll[Byte]]];
def registers: Rep[Size[Coll[WOption[AnyValue]]]];
def getReg[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]];
def tokens: Rep[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]]
};
trait CostedAvlTree extends CostedSigmaObject[AvlTree] {
def startingDigest: Rep[CostedColl[Byte]];
def keyLength: Rep[Costed[Int]];
def valueLengthOpt: Rep[CostedOption[Int]];
def maxNumOperations: Rep[CostedOption[Int]];
def maxDeletes: Rep[CostedOption[Int]]
@Liftable trait SizeContext extends Size[Context] {
def outputs: Rep[Size[Coll[Box]]];
def inputs: Rep[Size[Coll[Box]]];
def dataInputs: Rep[Size[Coll[Box]]];
def selfBox: Rep[Size[Box]];
def lastBlockUtxoRootHash: Rep[Size[AvlTree]];
def headers: Rep[Size[Coll[Header]]];
def preHeader: Rep[Size[PreHeader]];
def getVar[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]]
};
trait CostedSigmaObjectCompanion;
trait CostedContextCompanion;
trait CostedBoxCompanion;
trait CostedAvlTreeCompanion
@Liftable trait SizeBuilder extends Def[SizeBuilder] {
def mkSizeAnyValue(tVal: Rep[WRType[Any]], valueSize: Rep[Size[Any]]): Rep[SizeAnyValue];
def mkSizeBox(propositionBytes: Rep[Size[Coll[Byte]]], bytes: Rep[Size[Coll[Byte]]], bytesWithoutRef: Rep[Size[Coll[Byte]]], registers: Rep[Size[Coll[WOption[AnyValue]]]], tokens: Rep[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]]): Rep[SizeBox];
def mkSizeContext(outputs: Rep[Size[Coll[Box]]], inputs: Rep[Size[Coll[Box]]], dataInputs: Rep[Size[Coll[Box]]], selfBox: Rep[Size[Box]], lastBlockUtxoRootHash: Rep[Size[AvlTree]], headers: Rep[Size[Coll[Header]]], preHeader: Rep[Size[PreHeader]], vars: Rep[Coll[Size[AnyValue]]]): Rep[SizeContext]
};
trait SizeAnyValueCompanion;
trait SizeSigmaPropCompanion;
trait SizeBoxCompanion;
trait SizeContextCompanion;
trait SizeBuilderCompanion
}
}
85 changes: 43 additions & 42 deletions sigma-api/src/main/resources/special/sigma/SigmaDsl.scalan
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,16 @@ package special.sigma {
import Context._;
import CostModel._;
import CostedBuilder._;
import CostedColl._;
import CostedOption._;
import GroupElement._;
import Header._;
import MonoidBuilder._;
import Preheader._;
import PreHeader._;
import SigmaContract._;
import SigmaDslBuilder._;
import SigmaProp._;
import WBigInteger._;
import WOption._;
import WRType._;
@Liftable trait CostModel extends Def[CostModel] {
def AccessBox: Rep[Int];
def AccessAvlTree: Rep[Int];
Expand All @@ -33,7 +32,7 @@ package special.sigma {
def CollectionConst: Rep[Int];
def AccessKiloByteOfData: Rep[Int];
@Reified(value = "T") def dataSize[T](x: Rep[T])(implicit cT: Elem[T]): Rep[Long];
def PubKeySize: Rep[Long] = toRep(32L.asInstanceOf[Long])
def PubKeySize: Rep[Long]
};
@Liftable trait BigInt extends Def[BigInt] {
def toByte: Rep[Byte];
Expand Down Expand Up @@ -62,10 +61,10 @@ package special.sigma {
};
@Liftable trait GroupElement extends Def[GroupElement] {
def isInfinity: Rep[Boolean];
def multiply(k: Rep[BigInt]): Rep[GroupElement];
def add(that: Rep[GroupElement]): Rep[GroupElement];
def exp(k: Rep[BigInt]): Rep[GroupElement];
def multiply(that: Rep[GroupElement]): Rep[GroupElement];
def negate: Rep[GroupElement];
def getEncoded(compressed: Rep[Boolean]): Rep[Coll[Byte]]
def getEncoded: Rep[Coll[Byte]]
};
@Liftable trait SigmaProp extends Def[SigmaProp] {
def isValid: Rep[Boolean];
Expand All @@ -76,16 +75,15 @@ package special.sigma {
@OverloadId(value = "or_bool") def ||(other: Rep[Boolean]): Rep[SigmaProp]
};
@Liftable trait AnyValue extends Def[AnyValue] {
def dataSize: Rep[Long]
def value: Rep[Any];
def tVal: Rep[WRType[Any]]
};
@Liftable trait Box extends Def[Box] {
def id: Rep[Coll[Byte]];
def value: Rep[Long];
def propositionBytes: Rep[Coll[Byte]];
def bytes: Rep[Coll[Byte]];
def bytesWithoutRef: Rep[Coll[Byte]];
def cost: Rep[Int];
def dataSize: Rep[Long];
def registers: Rep[Coll[AnyValue]];
def getReg[T](i: Rep[Int])(implicit cT: Elem[T]): Rep[WOption[T]];
def R0[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(0.asInstanceOf[Int]));
Expand All @@ -103,53 +101,62 @@ package special.sigma {
def executeFromRegister[T](regId: Rep[Byte])(implicit cT: Elem[T]): Rep[T]
};
@Liftable trait AvlTree extends Def[AvlTree] {
def startingDigest: Rep[Coll[Byte]];
def digest: Rep[Coll[Byte]];
def enabledOperations: Rep[Byte];
def keyLength: Rep[Int];
def valueLengthOpt: Rep[WOption[Int]];
def maxNumOperations: Rep[WOption[Int]];
def maxDeletes: Rep[WOption[Int]];
def cost: Rep[Int];
def dataSize: Rep[Long];
def digest: Rep[Coll[Byte]]
def isInsertAllowed: Rep[Boolean];
def isUpdateAllowed: Rep[Boolean];
def isRemoveAllowed: Rep[Boolean];
def updateDigest(newDigest: Rep[Coll[Byte]]): Rep[AvlTree];
def updateOperations(newOperations: Rep[Byte]): Rep[AvlTree];
def contains(key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[Boolean];
def get(key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[WOption[Coll[Byte]]];
def getMany(keys: Rep[Coll[Coll[Byte]]], proof: Rep[Coll[Byte]]): Rep[Coll[WOption[Coll[Byte]]]];
def insert(operations: Rep[Coll[scala.Tuple2[Coll[Byte], Coll[Byte]]]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]];
def update(operations: Rep[Coll[scala.Tuple2[Coll[Byte], Coll[Byte]]]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]];
def remove(operations: Rep[Coll[Coll[Byte]]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]]
};
trait Header extends Def[Header] {
@Liftable trait PreHeader extends Def[PreHeader] {
def version: Rep[Byte];
def parentId: Rep[Coll[Byte]];
def ADProofsRoot: Rep[Coll[Byte]];
def stateRoot: Rep[Coll[Byte]];
def transactionsRoot: Rep[Coll[Byte]];
def timestamp: Rep[Long];
def nBits: Rep[Long];
def height: Rep[Int];
def extensionRoot: Rep[Coll[Byte]];
def minerPk: Rep[GroupElement];
def powOnetimePk: Rep[GroupElement];
def powNonce: Rep[Coll[Byte]];
def powDistance: Rep[BigInt]
def votes: Rep[Coll[Byte]]
};
trait Preheader extends Def[Preheader] {
@Liftable trait Header extends Def[Header] {
def id: Rep[Coll[Byte]];
def version: Rep[Byte];
def parentId: Rep[Coll[Byte]];
def ADProofsRoot: Rep[Coll[Byte]];
def stateRoot: Rep[AvlTree];
def transactionsRoot: Rep[Coll[Byte]];
def timestamp: Rep[Long];
def nBits: Rep[Long];
def height: Rep[Int];
def minerPk: Rep[GroupElement]
def extensionRoot: Rep[Coll[Byte]];
def minerPk: Rep[GroupElement];
def powOnetimePk: Rep[GroupElement];
def powNonce: Rep[Coll[Byte]];
def powDistance: Rep[BigInt];
def votes: Rep[Coll[Byte]]
};
@Liftable trait Context extends Def[Context] {
def builder: Rep[SigmaDslBuilder];
def OUTPUTS: Rep[Coll[Box]];
def INPUTS: Rep[Coll[Box]];
def dataInputs: Rep[Coll[Box]];
def HEIGHT: Rep[Int];
def SELF: Rep[Box];
def selfBoxIndex: Rep[Int];
def LastBlockUtxoRootHash: Rep[AvlTree];
def headers: Rep[Coll[Header]];
def preheader: Rep[Preheader];
def MinerPubKey: Rep[Coll[Byte]];
def preHeader: Rep[PreHeader];
def minerPubKey: Rep[Coll[Byte]];
def getVar[T](id: Rep[Byte])(implicit cT: Elem[T]): Rep[WOption[T]];
def getConstant[T](id: Rep[Byte])(implicit cT: Elem[T]): Rep[T];
def cost: Rep[Int];
def dataSize: Rep[Long]
def vars: Rep[Coll[AnyValue]]
};
@Liftable trait SigmaContract extends Def[SigmaContract] {
def builder: Rep[SigmaDslBuilder];
Expand All @@ -160,17 +167,16 @@ package special.sigma {
def allZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = this.builder.allZK(conditions);
def anyOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = this.builder.anyOf(conditions);
def anyZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = this.builder.anyZK(conditions);
def xorOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = this.builder.xorOf(conditions);
def PubKey(base64String: Rep[String]): Rep[SigmaProp] = this.builder.PubKey(base64String);
def sigmaProp(b: Rep[Boolean]): Rep[SigmaProp] = this.builder.sigmaProp(b);
def blake2b256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = this.builder.blake2b256(bytes);
def sha256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = this.builder.sha256(bytes);
def byteArrayToBigInt(bytes: Rep[Coll[Byte]]): Rep[BigInt] = this.builder.byteArrayToBigInt(bytes);
def longToByteArray(l: Rep[Long]): Rep[Coll[Byte]] = this.builder.longToByteArray(l);
def byteArrayToLong(bytes: Rep[Coll[Byte]]): Rep[Long] = this.builder.byteArrayToLong(bytes);
def proveDlog(g: Rep[GroupElement]): Rep[SigmaProp] = this.builder.proveDlog(g);
def proveDHTuple(g: Rep[GroupElement], h: Rep[GroupElement], u: Rep[GroupElement], v: Rep[GroupElement]): Rep[SigmaProp] = this.builder.proveDHTuple(g, h, u, v);
def isMember(tree: Rep[AvlTree], key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[Boolean] = this.builder.isMember(tree, key, proof);
def treeLookup(tree: Rep[AvlTree], key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[WOption[Coll[Byte]]] = this.builder.treeLookup(tree, key, proof);
def treeModifications(tree: Rep[AvlTree], operations: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[WOption[Coll[Byte]]] = this.builder.treeModifications(tree, operations, proof);
def groupGenerator: Rep[GroupElement] = this.builder.groupGenerator;
@clause def canOpen(ctx: Rep[Context]): Rep[Boolean];
def asFunction: Rep[scala.Function1[Context, Boolean]] = fun(((ctx: Rep[Context]) => this.canOpen(ctx)))
Expand All @@ -180,9 +186,6 @@ package special.sigma {
def Monoids: Rep[MonoidBuilder];
def Costing: Rep[CostedBuilder];
def CostModel: Rep[CostModel];
def costBoxes(bs: Rep[Coll[Box]]): Rep[CostedColl[Box]];
def costColWithConstSizedItem[T](xs: Rep[Coll[T]], len: Rep[Int], itemSize: Rep[Long]): Rep[CostedColl[T]];
def costOption[T](opt: Rep[WOption[T]], opCost: Rep[Int]): Rep[CostedOption[T]];
def verifyZK(cond: Rep[Thunk[SigmaProp]]): Rep[Boolean];
def atLeast(bound: Rep[Int], props: Rep[Coll[SigmaProp]]): Rep[SigmaProp];
def allOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean];
Expand All @@ -199,14 +202,12 @@ package special.sigma {
def byteArrayToLong(bytes: Rep[Coll[Byte]]): Rep[Long];
def proveDlog(g: Rep[GroupElement]): Rep[SigmaProp];
def proveDHTuple(g: Rep[GroupElement], h: Rep[GroupElement], u: Rep[GroupElement], v: Rep[GroupElement]): Rep[SigmaProp];
def isMember(tree: Rep[AvlTree], key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[Boolean];
def treeLookup(tree: Rep[AvlTree], key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[WOption[Coll[Byte]]];
def treeModifications(tree: Rep[AvlTree], operations: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[WOption[Coll[Byte]]];
def groupGenerator: Rep[GroupElement];
@Reified(value = "T") def substConstants[T](scriptBytes: Rep[Coll[Byte]], positions: Rep[Coll[Int]], newValues: Rep[Coll[T]])(implicit cT: Elem[T]): Rep[Coll[Byte]];
def decodePoint(encoded: Rep[Coll[Byte]]): Rep[GroupElement];
def BigInt(n: Rep[WBigInteger]): Rep[BigInt];
def toBigInteger(n: Rep[BigInt]): Rep[WBigInteger]
def toBigInteger(n: Rep[BigInt]): Rep[WBigInteger];
def avlTree(operationFlags: Rep[Byte], digest: Rep[Coll[Byte]], keyLength: Rep[Int], valueLengthOpt: Rep[WOption[Int]]): Rep[AvlTree]
};
trait CostModelCompanion;
trait BigIntCompanion;
Expand All @@ -215,8 +216,8 @@ package special.sigma {
trait AnyValueCompanion;
trait BoxCompanion;
trait AvlTreeCompanion;
trait PreHeaderCompanion;
trait HeaderCompanion;
trait PreheaderCompanion;
trait ContextCompanion;
trait SigmaContractCompanion;
trait SigmaDslBuilderCompanion
Expand Down
1 change: 1 addition & 0 deletions sigma-api/src/main/scala/sigma/types/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ package types {

case class PrimViewType[T, Val](classTag: ClassTag[T], tVal: RType[Val]) extends ViewType[T, Val] {
override def name: String = tVal.name
override def isConstantSize: scala.Boolean = tVal.isConstantSize
}

object IsPrimView {
Expand Down
2 changes: 0 additions & 2 deletions sigma-api/src/main/scala/special/contracts/Annotations.scala

This file was deleted.

Loading

0 comments on commit 94cc64d

Please sign in to comment.