Skip to content

Commit

Permalink
Merge branch 'version-1.5.x' into NODE-2496
Browse files Browse the repository at this point in the history
  • Loading branch information
phearnot authored Sep 29, 2023
2 parents ba4f4c1 + 8d1e7ba commit e560077
Show file tree
Hide file tree
Showing 39 changed files with 700 additions and 248 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ object EnvironmentFunctionsBenchmark {

override def accountScript(addressOrAlias: Recipient): Option[Script] = ???

override def calculateDelay(hitSource: ByteStr, baseTarget: Long, generator: ByteStr, balance: Long): Long = ???

def callScript(
dApp: Address,
func: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.wavesplatform.lang.v1

import com.wavesplatform.common.utils.EitherExt2
import com.wavesplatform.lang.Common
import com.wavesplatform.lang.directives.values.StdLibVersion
import com.wavesplatform.lang.v1.FunctionHeader.Native
import com.wavesplatform.lang.v1.compiler.Terms.*
import com.wavesplatform.lang.v1.evaluator.FunctionIds.REPLACE_BY_INDEX_OF_LIST
import com.wavesplatform.lang.v1.evaluator.ctx.impl.PureContext
import com.wavesplatform.lang.v1.traits.Environment
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole

import scala.concurrent.duration.{MICROSECONDS, SECONDS}

@OutputTimeUnit(MICROSECONDS)
@BenchmarkMode(Array(Mode.AverageTime))
@Threads(1)
@Fork(1)
@Warmup(iterations = 10, time = 1, timeUnit = SECONDS)
@Measurement(iterations = 10, time = 1, timeUnit = SECONDS)
class ListReplaceByIndexBenchmark {
@Benchmark
def listReplaceFirstByIndex(st: ListReplaceByIndexSt, bh: Blackhole): Unit =
bh.consume(eval(st.ctx, st.replaceFirst))

@Benchmark
def listReplaceMiddleByIndex(st: ListReplaceByIndexSt, bh: Blackhole): Unit =
bh.consume(eval(st.ctx, st.replaceMiddle))

@Benchmark
def listReplaceLastByIndex(st: ListReplaceByIndexSt, bh: Blackhole): Unit =
bh.consume(eval(st.ctx, st.replaceLast))
}

@State(Scope.Benchmark)
class ListReplaceByIndexSt {
val ctx =
PureContext
.build(StdLibVersion.VersionDic.all.max, useNewPowPrecision = true)
.withEnvironment[Environment]
.evaluationContext(Common.emptyBlockchainEnvironment())

val list = ARR(Vector.fill(1000)(CONST_LONG(Long.MaxValue)), limited = true).explicitGet()

val replaceFirst =
FUNCTION_CALL(
Native(REPLACE_BY_INDEX_OF_LIST),
List(
list,
CONST_LONG(0),
CONST_LONG(777)
)
)

val replaceMiddle =
FUNCTION_CALL(
Native(REPLACE_BY_INDEX_OF_LIST),
List(
list,
CONST_LONG(500),
CONST_LONG(777)
)
)

val replaceLast =
FUNCTION_CALL(
Native(REPLACE_BY_INDEX_OF_LIST),
List(
list,
CONST_LONG(999),
CONST_LONG(777)
)
)
}
Original file line number Diff line number Diff line change
@@ -1,100 +1,97 @@
package com.wavesplatform.lang.v1

import java.util.concurrent.TimeUnit

import cats.Id
import cats.kernel.Monoid
import cats.implicits.catsSyntaxSemigroup
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.common.utils.{Base58, EitherExt2}
import com.wavesplatform.crypto.Curve25519
import com.wavesplatform.lang.Global
import com.wavesplatform.lang.directives.values.{V1, V4}
import com.wavesplatform.lang.directives.values.StdLibVersion
import com.wavesplatform.lang.v1.EnvironmentFunctionsBenchmark.{curve25519, randomBytes}
import com.wavesplatform.lang.v1.FunctionHeader.Native
import com.wavesplatform.lang.v1.ScriptEvaluatorBenchmark.*
import com.wavesplatform.lang.v1.compiler.Terms.*
import com.wavesplatform.lang.v1.evaluator.Contextful.NoContext
import com.wavesplatform.lang.v1.evaluator.EvaluatorV1.*
import com.wavesplatform.lang.v1.evaluator.FunctionIds
import com.wavesplatform.lang.v1.evaluator.FunctionIds.{FROMBASE58, SIGVERIFY, TOBASE58}
import com.wavesplatform.lang.v1.evaluator.ctx.EvaluationContext
import com.wavesplatform.lang.v1.evaluator.ctx.impl.{CryptoContext, PureContext}
import com.wavesplatform.lang.v1.evaluator.{EvaluatorV1, FunctionIds}
import com.wavesplatform.lang.v1.traits.Environment
import com.wavesplatform.lang.{Common, Global}
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole

import java.util.concurrent.TimeUnit
import scala.concurrent.duration.SECONDS
import scala.util.Random

object ScriptEvaluatorBenchmark {
val version = V1
val pureEvalContext: EvaluationContext[NoContext, Id] =
PureContext.build(V1, useNewPowPrecision = true).evaluationContext
val evaluatorV1: EvaluatorV1[Id, NoContext] = new EvaluatorV1[Id, NoContext]()
val lastVersion = StdLibVersion.VersionDic.all.max
val context =
(PureContext.build(lastVersion, useNewPowPrecision = true) |+| CryptoContext.build(Global, lastVersion))
.withEnvironment[Environment]
.evaluationContext(Common.emptyBlockchainEnvironment())
}

@OutputTimeUnit(TimeUnit.MICROSECONDS)
@BenchmarkMode(Array(Mode.AverageTime))
@Threads(1)
@Fork(1)
@Warmup(iterations = 10)
@Measurement(iterations = 10)
@Warmup(iterations = 10, time = 1, timeUnit = SECONDS)
@Measurement(iterations = 10, time = 1, timeUnit = SECONDS)
class ScriptEvaluatorBenchmark {
@Benchmark
def bigSum(st: BigSum, bh: Blackhole): Unit = bh.consume(evaluatorV1.apply[EVALUATED](pureEvalContext, st.expr))
def bigSum(st: BigSum, bh: Blackhole): Unit = bh.consume(eval(context, st.expr))

@Benchmark
def nestedBlocks(st: NestedBlocks, bh: Blackhole): Unit = bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.expr))
def nestedBlocks(st: NestedBlocks, bh: Blackhole): Unit = bh.consume(eval(context, st.expr))

@Benchmark
def signatures(st: Signatures, bh: Blackhole): Unit = bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.expr))
def signatures(st: Signatures, bh: Blackhole): Unit = bh.consume(eval(context, st.expr))

@Benchmark
def base58encode(st: Base58Perf, bh: Blackhole): Unit = bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.encode))
def base58encode(st: Base58Perf, bh: Blackhole): Unit = bh.consume(eval(context, st.encode))

@Benchmark
def base58decode(st: Base58Perf, bh: Blackhole): Unit = bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.decode))
def base58decode(st: Base58Perf, bh: Blackhole): Unit = bh.consume(eval(context, st.decode))

@Benchmark
def stringConcat(st: Concat, bh: Blackhole): Unit = bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.strings))
def stringConcat(st: Concat, bh: Blackhole): Unit = bh.consume(eval(context, st.strings))

@Benchmark
def bytesConcat(st: Concat, bh: Blackhole): Unit = bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.bytes))
def bytesConcat(st: Concat, bh: Blackhole): Unit = bh.consume(eval(context, st.bytes))

@Benchmark
def listMedianRandomElements(st: Median, bh: Blackhole): Unit =
bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.randomElements(Random.nextInt(10000))))
bh.consume(eval(context, st.randomElements(Random.nextInt(10000))))

@Benchmark
def listMedianSortedElements(st: Median, bh: Blackhole): Unit =
bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.sortedElements))
bh.consume(eval(context, st.sortedElements))

@Benchmark
def listMedianSortedReverseElements(st: Median, bh: Blackhole): Unit =
bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.sortedReverseElements))
bh.consume(eval(context, st.sortedReverseElements))

@Benchmark
def listMedianEqualElements(st: Median, bh: Blackhole): Unit =
bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.equalElements))
bh.consume(eval(context, st.equalElements))

@Benchmark
def listRemoveFirstByIndex(st: ListRemoveByIndex, bh: Blackhole): Unit =
bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.removeFirst))
bh.consume(eval(context, st.removeFirst))

@Benchmark
def listRemoveMiddleByIndex(st: ListRemoveByIndex, bh: Blackhole): Unit =
bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.removeMiddle))
bh.consume(eval(context, st.removeMiddle))

@Benchmark
def listRemoveLastByIndex(st: ListRemoveByIndex, bh: Blackhole): Unit =
bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.removeLast))
bh.consume(eval(context, st.removeLast))

@Benchmark
def sigVerify32Kb(st: SigVerify32Kb, bh: Blackhole): Unit = bh.consume(evaluatorV1.apply[EVALUATED](st.context, st.expr))
def sigVerify32Kb(st: SigVerify32Kb, bh: Blackhole): Unit =
bh.consume(eval(context, st.expr))
}

@State(Scope.Benchmark)
class NestedBlocks {
val context: EvaluationContext[NoContext, Id] = pureEvalContext

val expr: EXPR = {
val blockCount = 300
val cond = FUNCTION_CALL(PureContext.eq, List(REF(s"v$blockCount"), CONST_LONG(0)))
Expand All @@ -107,9 +104,6 @@ class NestedBlocks {

@State(Scope.Benchmark)
class Base58Perf {
val context: EvaluationContext[NoContext, Id] =
Monoid.combine(pureEvalContext, CryptoContext.build(Global, version).evaluationContext)

val encode: EXPR = {
val base58Count = 120
val sum = (1 to base58Count).foldRight[EXPR](CONST_LONG(0)) { case (i, e) =>
Expand Down Expand Up @@ -150,9 +144,6 @@ class Base58Perf {

@State(Scope.Benchmark)
class Signatures {
val context: EvaluationContext[NoContext, Id] =
Monoid.combine(pureEvalContext, CryptoContext.build(Global, version).evaluationContext)

val expr: EXPR = {
val sigCount = 20
val sum = (1 to sigCount).foldRight[EXPR](CONST_LONG(0)) { case (i, e) =>
Expand Down Expand Up @@ -191,8 +182,6 @@ class Signatures {

@State(Scope.Benchmark)
class Concat {
val context: EvaluationContext[NoContext, Id] = pureEvalContext

private val Steps = 180

private def expr(init: EXPR, func: FunctionHeader, operand: EXPR, count: Int) =
Expand All @@ -218,8 +207,6 @@ class Concat {

@State(Scope.Benchmark)
class Median {
val context: EvaluationContext[NoContext, Id] = PureContext.build(V4, useNewPowPrecision = true).evaluationContext

val randomElements: Array[EXPR] =
(1 to 10000).map { _ =>
val listOfLong = (1 to 1000).map(_ => CONST_LONG(Random.nextLong()))
Expand Down Expand Up @@ -260,9 +247,6 @@ class Median {

@State(Scope.Benchmark)
class SigVerify32Kb {
val context: EvaluationContext[NoContext, Id] =
Monoid.combine(PureContext.build(V4, useNewPowPrecision = true).evaluationContext, CryptoContext.build(Global, V4).evaluationContext)

val expr: EXPR = {
val (privateKey, publicKey) = curve25519.generateKeypair
val message = randomBytes(32 * 1024 - 1)
Expand All @@ -281,12 +265,6 @@ class SigVerify32Kb {

@State(Scope.Benchmark)
class ListRemoveByIndex {
val context: EvaluationContext[NoContext, Id] =
Monoid.combine(
PureContext.build(V4, useNewPowPrecision = true).evaluationContext,
CryptoContext.build(Global, V4).evaluationContext
)

val list: ARR = ARR(Vector.fill(1000)(CONST_LONG(Long.MaxValue)), limited = true).explicitGet()

val removeFirst: EXPR =
Expand All @@ -312,7 +290,7 @@ class ListRemoveByIndex {
Native(FunctionIds.REMOVE_BY_INDEX_OF_LIST),
List(
list,
CONST_LONG(1000)
CONST_LONG(999)
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ package object v1 {
def eval(
ctx: EvaluationContext[Environment, Id],
expr: EXPR,
stdLibVersion: StdLibVersion
stdLibVersion: StdLibVersion = StdLibVersion.VersionDic.all.max
): (Log[Id], Int, Either[ExecutionError, Terms.EVALUATED]) =
EvaluatorV2.applyCompleted(ctx, expr, LogExtraInfo(), stdLibVersion, newMode = true, correctFunctionCallScope = true, enableExecutionLog = false)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.wavesplatform.state

import com.wavesplatform.common.state.ByteStr
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole

import java.util.concurrent.TimeUnit

/*
[info] Benchmark (configFile) Mode Cnt Score Error Units
[info] CalculateDelayBenchmark.calculateDelay1 waves.conf avgt 10 1,616 ± 0,244 us/op
[info] CalculateDelayBenchmark.calculateDelay2 waves.conf avgt 10 1,671 ± 0,073 us/op
[info] CalculateDelayBenchmark.calculateDelay3 waves.conf avgt 10 1,688 ± 0,228 us/op
[info] CalculateDelayBenchmark.calculateDelay4 waves.conf avgt 10 1,656 ± 0,020 us/op
*/

@OutputTimeUnit(TimeUnit.MICROSECONDS)
@BenchmarkMode(Array(Mode.AverageTime))
@Threads(1)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 10, time = 1)
class CalculateDelayBenchmark {
import CalculateDelayBenchmark.*

@Benchmark
def calculateDelay1(bh: Blackhole, st: St): Unit =
bh.consume(st.environment.calculateDelay(ByteStr.empty, 0, ByteStr.empty, 0))

@Benchmark
def calculateDelay2(bh: Blackhole, st: St): Unit =
bh.consume(
st.environment.calculateDelay(ByteStr.fill(96)(127), Long.MaxValue, ByteStr.fill(26)(127), Long.MaxValue)
)

@Benchmark
def calculateDelay3(bh: Blackhole, st: St): Unit =
bh.consume(
st.environment.calculateDelay(ByteStr.fill(96)(-128), Long.MinValue, ByteStr.fill(26)(-128), Long.MinValue)
)

@Benchmark
def calculateDelay4(bh: Blackhole, st: St): Unit =
bh.consume(
st.environment.calculateDelay(ByteStr.fill(32)(32), 123456, ByteStr.fill(26)(32), 100_000_000)
)
}

object CalculateDelayBenchmark {
class St extends DBState {}
}
7 changes: 7 additions & 0 deletions lang/doc/v8/funcs/blockchain-functions.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,12 @@
paramsDoc: [ "dApp", "function name", "arguments", "Attached payments" ]
complexity: 75
}
{
name: "calculateDelay"
params: [ "ByteVector", "Int", "Address", "Int" ]
doc: "Calculates mining delay using Fair PoS calculator."
paramsDoc: [ "hit source", "base target", "generator address", "generator balance" ]
complexity: 1
}
]
}
11 changes: 9 additions & 2 deletions lang/doc/v8/funcs/list-functions.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,15 @@
name: "removeByIndex"
params: [ "List[T]", "Int" ]
doc: "Removes the element at given index from the list and returns new list."
paramsDoc: [ "The list.", "The element." ]
complexity: 7
paramsDoc: [ "The list.", "The index." ]
complexity: 4
}
{
name: "replaceByIndex"
params: [ "List[T]", "Int", "T" ]
doc: "Replaces the element at given index in the list and returns new list."
paramsDoc: [ "The list.", "The index.", "New element." ]
complexity: 4
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ package object utils {
override def addressFromString(address: String): Either[String, Recipient.Address] = ???
override def addressFromPublicKey(publicKey: ByteStr): Either[String, Address] = ???
override def accountScript(addressOrAlias: Recipient): Option[Script] = ???
override def calculateDelay(hs: ByteStr, bt: Long, gt: ByteStr, b: Long): Long = ???
override def callScript(
dApp: Address,
func: String,
Expand Down
Loading

0 comments on commit e560077

Please sign in to comment.