Skip to content

Commit

Permalink
Merge pull request #896 from ScorexFoundation/refactoring
Browse files Browse the repository at this point in the history
Refactoring and improvments
  • Loading branch information
aslesarenko authored Aug 11, 2023
2 parents 5d03858 + 39e793b commit b81849e
Show file tree
Hide file tree
Showing 50 changed files with 401 additions and 917 deletions.
3 changes: 2 additions & 1 deletion common/shared/src/test/scala/scalan/BaseTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ abstract class BaseShouldTests extends AnyFlatSpec with TestUtils {
}
}

protected implicit def convertToInAndIgnoreMethods2(resultOfStringPassedToVerb: ResultOfStringPassedToVerb) =
protected implicit def convertToInAndIgnoreMethods2(
resultOfStringPassedToVerb: ResultOfStringPassedToVerb): InAndIgnoreMethods2 =
new InAndIgnoreMethods2(resultOfStringPassedToVerb)

}
446 changes: 0 additions & 446 deletions docs/Costing.md

This file was deleted.

56 changes: 56 additions & 0 deletions docs/ergoscript-compiler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

# ErgoScript Compiler

Sigma frontend implements the following pipeline:

`SourceCode` --> `parse` --> `bind` -> `typecheck` -> `buildGraph` -> `buildTree` -> `ErgoTree`

Here:
- `SourceCode` - a string of unicode characters
- `parse` - method `SigmaCompiler.parse`
- `bind` - method `SigmaBinder.bind`
- `typecheck` - method `SigmaTyper.typecheck`
- `buildGraph` - method `IRContext.buildGraph`
- `buildTree` - method `IRContext.buildTree`
- `ErgoTree` - an intermediate representation which can be processed by Sigma [Interpreter](https://github.com/ScorexFoundation/sigmastate-interpreter/blob/master/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala#L46)

## Parser
`parse` takes a string and produces abstract syntax tree, AST, of a Sigma expression represented by `Value` type in Scala.

In case of any errors it throws `ParserException`

## Binder
`SigmaBinder` takes an AST of successfully parsed Sigma expression and resolves
global variables and predefined functions that are looked up in the provided environment.
Binder transforms environment values of predefined Scala types (such as Int, Boolean, Box, etc.)
into constant nodes (IntConstant, BoxConstant, etc) of the corresponding type. (See also `Constant` class)

In case of any error it throws `BinderException`

## Typer
`SigmaTyper` takes an AST from the output of `SigmaBinder` and assigns types
to all tree nodes. Since AST is immutable data structure the typer produces a new tree.

Type assignment is performed by `assignType` tree transformation which assign correct types for all
tree nodes.

In case of any error it throws `TyperException`

## Graph Building

`IRContext.buildGraph` takes an AST from the output of `SigmaTyper` and builds a graph where nodes are operations and edges are dependencies between operations.
During graph building the following optimizations are performed:
- constant propagation
- common subexpression elimination
- dead code elimination

## Tree Building

`IRContext.buildTree` takes a graph from the output of `IRContext.buildGraph` and builds the resulting ErgoTree.

## IR contexts

- `IRContext` - the main interface of graph IR which mixes in both GraphBuilding and TreeBuilding traits.
Since v5.0 it is not used by Interpreter and thus not part of consensus.

- `CompiletimeIRContext` - the main implementation of IRContext
14 changes: 7 additions & 7 deletions docs/notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@

These dependencies can be removed with refactoring

| Jar | Size, Kb |
|---------------|---------------|
| - jline-2.14.3.jar | 268 |
| cats-core_2.12-1.4.0.jar | 4400 |
| - cats-kernel_2.12-1.4.0.jar | 3200 |
| - algebra_2.12-0.7.0.jar | 1100 |
| - spire-macros_2.12-0.14.1.jar | 73 |
| Jar | Size, Kb |
|--------------------------------|----------|
| - jline-3.10.0.jar | 715 |
| cats-core_2.12-2.1.0.jar | 4900 |
| - cats-kernel_2.12-1.4.0.jar | 3500 |
| - algebra_2.12-2.0.0-M2.jar | 1400 |
| - spire-macros_2.12-0.14.1.jar | 79 |



Expand Down
21 changes: 0 additions & 21 deletions docs/releasenotes.md

This file was deleted.

8 changes: 3 additions & 5 deletions docs/sigma-dsl.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
code directly in Scala IDE (e.g. IntelliJ IDEA) and copy-paste code snippets
between SigmaDsl and SigmaScript.
Special Scala macros can also be used to automatically translate SigmaDsl to
Sigma byte code.

SigmaDsl is implemented as Scala library using [Special](https://github.com/scalan/special)
framework.
Sigma byte code. Some prototype has been implemented [here](https://github.com/ergoplatform/ergo-scala-compiler)

## See also
[Special](https://github.com/scalan/special)

[ergo-scala-compiler](https://github.com/ergoplatform/ergo-scala-compiler)
55 changes: 0 additions & 55 deletions docs/sigma-front-end.md

This file was deleted.

38 changes: 0 additions & 38 deletions docs/soft-fork-log.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class WOptionCls extends EntityObject("WOption") {
case class WOptionAdapter[A](source: Ref[WOption[A]])
extends Node with WOption[A]
with Def[WOption[A]] {
implicit lazy val eA = source.elem.typeArgs("A")._1.asInstanceOf[Elem[A]]
implicit lazy val eA: Elem[A] = source.elem.typeArgs("A")._1.asInstanceOf[Elem[A]]

val resultType: Elem[WOption[A]] = element[WOption[A]]
override def transform(t: Transformer) = WOptionAdapter[A](t(source))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class WRTypeCls extends EntityObject("WRType") {
case class WRTypeAdapter[A](source: Ref[WRType[A]])
extends Node with WRType[A]
with Def[WRType[A]] {
implicit lazy val eA = source.elem.typeArgs("A")._1.asInstanceOf[Elem[A]]
implicit lazy val eA: Elem[A] = source.elem.typeArgs("A")._1.asInstanceOf[Elem[A]]

val resultType: Elem[WRType[A]] = element[WRType[A]]
override def transform(t: Transformer) = WRTypeAdapter[A](t(source))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,6 @@ object SigmaConstants {
"Max children count should not be greater than provided value") {
}

object ScriptCostLimit extends SizeConstant[Int](1000000, 12,
"Maximum execution cost of a script") {
}

object MaxLoopLevelInCostFunction extends SizeConstant[Int](1, 13,
"Maximum allowed loop level in a cost function") {
}
Expand All @@ -96,7 +92,6 @@ object SigmaConstants {
MaxTupleLength,
MaxHeaders,
MaxChildrenCountForAtLeastOp,
ScriptCostLimit,
MaxLoopLevelInCostFunction,
VotesArraySize,
AutolykosPowSolutionNonceArraySize
Expand Down
19 changes: 10 additions & 9 deletions interpreter/shared/src/main/scala/sigmastate/SigSerializer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import scorex.util.encode.Base16
import sigmastate.Values.SigmaBoolean
import sigmastate.basics.DLogProtocol.{ProveDlog, SecondDLogProverMessage}
import sigmastate.basics.VerifierMessage.Challenge
import sigmastate.basics.{SecondDiffieHellmanTupleProverMessage, ProveDHTuple, CryptoConstants}
import sigmastate.basics.{CryptoConstants, ProveDHTuple, SecondDHTupleProverMessage}
import sigmastate.interpreter.ErgoTreeEvaluator.{fixedCostOp, perItemCostOp}
import sigmastate.interpreter.{ErgoTreeEvaluator, NamedDesc, OperationCostInfo}
import sigmastate.serialization.SigmaSerializer
import sigmastate.util.safeNewArray
import sigmastate.utils.{Helpers, SigmaByteReader, SigmaByteWriter}
import debox.cfor
import sigmastate.eval.Extensions.ArrayOps
import sigmastate.exceptions.SerializerException

/** Contains implementation of signature (aka proof) serialization.
Expand Down Expand Up @@ -61,7 +62,7 @@ class SigSerializer {
w: SigmaByteWriter,
writeChallenge: Boolean): Unit = {
if (writeChallenge) {
w.putBytes(node.challenge)
w.putBytes(node.challenge.toArray)
}
node match {
case dl: UncheckedSchnorr =>
Expand Down Expand Up @@ -184,7 +185,7 @@ class SigSerializer {
// Verifier Step 2: Let e_0 be the challenge in the node here (e_0 is called "challenge" in the code)
val challenge = if (challengeOpt == null) {
Challenge @@ readBytesChecked(r, hashSize,
hex => warn(s"Invalid challenge in: $hex"))
hex => warn(s"Invalid challenge in: $hex")).toColl
} else {
challengeOpt
}
Expand All @@ -203,7 +204,7 @@ class SigSerializer {
fixedCostOp(ParseChallenge_ProveDHT) {
val z_bytes = readBytesChecked(r, order, hex => warn(s"Invalid z bytes for $dh: $hex"))
val z = BigIntegers.fromUnsignedByteArray(z_bytes)
UncheckedDiffieHellmanTuple(dh, None, challenge, SecondDiffieHellmanTupleProverMessage(z))
UncheckedDiffieHellmanTuple(dh, None, challenge, SecondDHTupleProverMessage(z))
}

case and: CAND =>
Expand All @@ -223,18 +224,18 @@ class SigSerializer {
// Read all the children but the last and compute the XOR of all the challenges including e_0
val nChildren = or.children.length
val children = safeNewArray[UncheckedSigmaTree](nChildren)
val xorBuf = challenge.clone()
val xorBuf = challenge.toArray.clone()
val iLastChild = nChildren - 1
cfor(0)(_ < iLastChild, _ + 1) { i =>
val parsedChild = parseAndComputeChallenges(or.children(i), r, null)
children(i) = parsedChild
Helpers.xorU(xorBuf, parsedChild.challenge) // xor it into buffer
Helpers.xorU(xorBuf, parsedChild.challenge.toArray) // xor it into buffer
}
val lastChild = or.children(iLastChild)

// use the computed XOR for last child's challenge
children(iLastChild) = parseAndComputeChallenges(
lastChild, r, challengeOpt = Challenge @@ xorBuf)
lastChild, r, challengeOpt = Challenge @@ xorBuf.toColl)

COrUncheckedNode(challenge, children)

Expand All @@ -248,13 +249,13 @@ class SigSerializer {
val polynomial = perItemCostOp(ParsePolynomial, nCoefs) { () =>
val coeffBytes = readBytesChecked(r, hashSize * nCoefs,
hex => warn(s"Invalid coeffBytes for $th: $hex"))
GF2_192_Poly.fromByteArray(challenge, coeffBytes)
GF2_192_Poly.fromByteArray(challenge.toArray, coeffBytes)
}

val children = safeNewArray[UncheckedSigmaTree](nChildren)
cfor(0)(_ < nChildren, _ + 1) { i =>
val c = perItemCostOp(EvaluatePolynomial, nCoefs) { () =>
Challenge @@ polynomial.evaluate((i + 1).toByte).toByteArray
Challenge @@ polynomial.evaluate((i + 1).toByte).toByteArray.toColl
}
children(i) = parseAndComputeChallenges(th.children(i), r, c)
}
Expand Down
Loading

0 comments on commit b81849e

Please sign in to comment.