Skip to content

Commit

Permalink
6.0 activation fixed, VersionedBlockchainStateContext
Browse files Browse the repository at this point in the history
  • Loading branch information
kushti committed Aug 26, 2024
1 parent 4e0e923 commit 66e269d
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,20 @@ import org.ergoplatform.modifiers.history.header.{Header, HeaderSerializer}
import org.ergoplatform.modifiers.history.popow.NipopowAlgos
import org.ergoplatform.nodeView.history.ErgoHistoryUtils
import org.ergoplatform.nodeView.history.storage.modifierprocessors.ExtensionValidator
import org.ergoplatform.sdk.wallet.protocol.context.BlockchainStateContext
import org.ergoplatform.settings.ValidationRules._
import org.ergoplatform.settings._
import org.ergoplatform.utils.ScorexEncoding
import org.ergoplatform.serialization.ErgoSerializer
import org.ergoplatform.validation.{InvalidModifier, ModifierValidator, ValidationState}
import org.ergoplatform.wallet.interpreter.VersionedBlockchainStateContext
import scorex.crypto.authds.ADDigest
import scorex.util.ScorexLogging
import scorex.util.serialization.{Reader, Writer}
import sigma.Coll
import sigma.eval.SigmaDsl
import sigma.Extensions.ArrayOps
import sigma.crypto.EcPointType
import sigma.validation.SigmaValidationSettings

import scala.collection.compat.immutable.ArraySeq
import scala.util.{Failure, Success, Try}
Expand Down Expand Up @@ -68,7 +69,7 @@ class ErgoStateContext(val lastHeaders: Seq[Header],
val validationSettings: ErgoValidationSettings,
val votingData: VotingData)
(implicit val chainSettings: ChainSettings)
extends BlockchainStateContext
extends VersionedBlockchainStateContext
with BytesSerializable
with ScorexEncoding
with ScorexLogging {
Expand All @@ -78,6 +79,8 @@ class ErgoStateContext(val lastHeaders: Seq[Header],
private val votingSettings = chainSettings.voting
private val popowAlgos = new NipopowAlgos(chainSettings)

override val sigmaValidationSettings: SigmaValidationSettings = validationSettings.sigmaSettings

override def sigmaPreHeader: sigma.PreHeader =
PreHeader.toSigma(lastHeaders.headOption.getOrElse(PreHeader.fake))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.nodeView.state.{ErgoStateContext, VotingData}
import org.ergoplatform.settings.ValidationRules.rulesSpec
import org.ergoplatform.utils.ErgoCorePropertyTest
import sigma.validation.{DisabledRule, ReplacedRule}
import sigma.validation.{DisabledRule, ReplacedRule, ValidationException}
import org.ergoplatform.validation.{ValidationRules => VR}
import scorex.crypto.authds.ADDigest
import sigmastate.utils.Helpers._

import scala.util.Try

Expand Down Expand Up @@ -59,6 +58,16 @@ class VotingSpecification extends ErgoCorePropertyTest {
}
}

property(".toExtensionCandidate && .parseExtension") {
val update = ErgoValidationSettingsUpdate(
Seq.empty,
Seq(1011.toShort -> ReplacedRule(1011), 1008.toShort -> ReplacedRule(1008))
)
val vs = ErgoValidationSettings.initial.updated(update)
val vs2 = ErgoValidationSettings.parseExtension(vs.toExtensionCandidate).get
vs2.updateFromInitial == vs.updateFromInitial
}

property("ErgoValidationSettings toExtension/fromExtension roundtrip") {
// initial settings should not be written into Extension at all
val initial = ErgoValidationSettings.initial
Expand Down Expand Up @@ -196,6 +205,8 @@ class VotingSpecification extends ErgoCorePropertyTest {
val esc12 = process(esc11, expectedParameters12, h12).get
checkValidationSettings(esc12.validationSettings, proposedUpdate)

esc12.validationSettings.sigmaSettings.isSoftFork(VR.CheckValidOpCode.id, ValidationException("", VR.CheckValidOpCode, Seq.empty)) shouldBe true

// vote for soft-fork @ activation height
val h12w = h12.copy(votes = forkVote)
process(esc11, expectedParameters12, h12w).isFailure shouldBe true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class ErgoProvingInterpreter(val secretKeys: IndexedSeq[SecretKey],
def signInputs(unsignedTx: UnsignedErgoLikeTransaction,
boxesToSpend: IndexedSeq[ErgoBox],
dataBoxes: IndexedSeq[ErgoBox],
stateContext: BlockchainStateContext,
stateContext: VersionedBlockchainStateContext,
txHints: TransactionHintsBag): Try[(IndexedSeq[Input], Long)] = {
if (unsignedTx.inputs.length != boxesToSpend.length) {
Failure(new Exception("Not enough boxes to spend"))
Expand Down Expand Up @@ -136,7 +136,7 @@ class ErgoProvingInterpreter(val secretKeys: IndexedSeq[SecretKey],
unsignedTx,
boxIdx.toShort,
unsignedInput.extension,
ValidationRules.currentSettings,
stateContext.sigmaValidationSettings,
params.maxBlockCost,
totalCost,
activatedScriptVersion
Expand Down Expand Up @@ -164,7 +164,7 @@ class ErgoProvingInterpreter(val secretKeys: IndexedSeq[SecretKey],
def sign(unsignedTx: UnsignedErgoLikeTransaction,
boxesToSpend: IndexedSeq[ErgoBox],
dataBoxes: IndexedSeq[ErgoBox],
stateContext: BlockchainStateContext,
stateContext: VersionedBlockchainStateContext,
txHints: TransactionHintsBag = TransactionHintsBag.empty): Try[ErgoLikeTransaction] = {

val signedInputs: Try[(IndexedSeq[Input], Long)] =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.ergoplatform.wallet.interpreter

import org.ergoplatform.sdk.wallet.protocol.context.BlockchainStateContext
import sigma.validation.SigmaValidationSettings

abstract class VersionedBlockchainStateContext extends BlockchainStateContext {
val sigmaValidationSettings: SigmaValidationSettings
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package org.ergoplatform.wallet.interpreter

import org.ergoplatform.sdk.BlockchainParameters
import org.ergoplatform.sdk.wallet.protocol.context.BlockchainStateContext
import org.ergoplatform.validation.ValidationRules
import scorex.util.encode.Base16
import sigma.Extensions.ArrayOps
import sigma.crypto.CryptoConstants
import sigma.data.CGroupElement
import sigma.validation.SigmaValidationSettings
import sigma.{Coll, Colls, Header, PreHeader}
import sigmastate.eval.CPreHeader

Expand Down Expand Up @@ -36,7 +38,9 @@ trait InterpreterSpecCommon {
override def blockVersion: Byte = 1
}

protected val stateContext = new BlockchainStateContext {
protected val stateContext = new VersionedBlockchainStateContext {

override val sigmaValidationSettings: SigmaValidationSettings = ValidationRules.currentSettings

override def sigmaLastHeaders: Coll[Header] = Colls.emptyColl

Expand Down
5 changes: 3 additions & 2 deletions src/main/resources/devnet.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ ergo {
protocolVersion = 4 # 6.0 soft-fork

# Network address prefix, currently reserved values are 0 (money chain mainnet) and 16 (money chain testnet)
addressPrefix = 32
addressPrefix = 16

# A difficulty the network starts with
initialDifficultyHex = "01"

Expand Down Expand Up @@ -52,7 +53,7 @@ ergo {

voting {
120 = 1
"rulesToDisable" = [1011, 1008]
"rulesToDisable" = []
}
}
scorex {
Expand Down
44 changes: 27 additions & 17 deletions src/main/scala/org/ergoplatform/http/api/ScriptApiRoute.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,18 @@ import org.ergoplatform._
import org.ergoplatform.http.api.ApiError.BadRequest
import org.ergoplatform.http.api.requests.{CryptoResult, ExecuteRequest}
import org.ergoplatform.nodeView.ErgoReadersHolder.{GetReaders, Readers}
import org.ergoplatform.nodeView.wallet.ErgoWalletReader
import org.ergoplatform.nodeView.wallet.requests.PaymentRequestDecoder
import org.ergoplatform.settings.{ErgoSettings, RESTApiSettings}
import scorex.core.api.http.ApiResponse
import scorex.util.encode.Base16
import sigma.VersionContext
import sigma.ast.{ByteArrayConstant, ErgoTree, SBoolean, SSigmaProp, Value}
import sigma.compiler.{CompilerResult, SigmaCompiler}
import sigma.compiler.ir.CompiletimeIRContext
import sigma.data.ProveDlog
import sigma.serialization.ValueSerializer
import sigmastate.interpreter.Interpreter

import scala.concurrent.Future
import scala.concurrent.duration._
import scala.util.{Failure, Success, Try}

Expand Down Expand Up @@ -58,37 +57,48 @@ case class ScriptApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings)
keys.zipWithIndex.map { case (pk, i) => s"myPubKey_$i" -> pk }.toMap
}

private def compileSource(source: String, env: Map[String, Any]): Try[ErgoTree] = {
private def compileSource(source: String, env: Map[String, Any], treeVersion: Int = 0): Try[ErgoTree] = {
val compiler = new SigmaCompiler(ergoSettings.chainSettings.addressPrefix)
val ergoTreeHeader = ErgoTree.defaultHeaderWithVersion(treeVersion.toByte)
Try(compiler.compile(env, source)(new CompiletimeIRContext)).flatMap {
case CompilerResult(_, _, _, script: Value[SSigmaProp.type@unchecked]) if script.tpe == SSigmaProp =>
Success(ErgoTree.fromProposition(script))
Success(ErgoTree.fromProposition(ergoTreeHeader, script))
case CompilerResult(_, _, _, script: Value[SBoolean.type@unchecked]) if script.tpe == SBoolean =>
Success(ErgoTree.fromProposition(script.toSigmaProp))
Success(ErgoTree.fromProposition(ergoTreeHeader, script.toSigmaProp))
case other =>
Failure(new Exception(s"Source compilation result is of type ${other.buildTree.tpe}, but `SBoolean` expected"))
}
}

private def withWalletOp[T](op: ErgoWalletReader => Future[T])(toRoute: T => Route): Route = {
onSuccess((readersHolder ? GetReaders).mapTo[Readers].flatMap(r => op(r.w)))(toRoute)
private def withWalletAndStateOp[T](op: (Readers) => T)(toRoute: T => Route): Route = {
onSuccess((readersHolder ? GetReaders).mapTo[Readers].map(r => op(r)))(toRoute)
}

// todo: unite p2sAddress and p2shAddress
def p2sAddressR: Route = (path("p2sAddress") & post & source) { source =>
withWalletOp(_.publicKeys(0, loadMaxKeys)) { addrs =>
compileSource(source, keysToEnv(addrs.map(_.pubkey))).map(Pay2SAddress.apply).fold(
e => BadRequest(e.getMessage),
address => ApiResponse(addressResponse(address))
)
withWalletAndStateOp(r => (r.w.publicKeys(0, loadMaxKeys), r.s.stateContext)) { case (addrsF, sc) =>
onSuccess(addrsF) { addrs =>
VersionContext.withVersions((sc.blockVersion - 1).toByte, 0) {
// todo: treeVersion == 1 is used here, revisit, likely 0 should be default for now
compileSource(source, keysToEnv(addrs.map(_.pubkey)), 1).map(Pay2SAddress.apply).fold(
e => BadRequest(e.getMessage),
address => ApiResponse(addressResponse(address))
)
}
}
}
}

def p2shAddressR: Route = (path("p2shAddress") & post & source) { source =>
withWalletOp(_.publicKeys(0, loadMaxKeys)) { addrs =>
compileSource(source, keysToEnv(addrs.map(_.pubkey))).map(Pay2SHAddress.apply).fold(
e => BadRequest(e.getMessage),
address => ApiResponse(addressResponse(address))
)
withWalletAndStateOp(r => (r.w.publicKeys(0, loadMaxKeys), r.s.stateContext.blockVersion)) { case (addrsF, bv) =>
onSuccess(addrsF) { addrs =>
VersionContext.withVersions((bv - 1).toByte, 0) {
compileSource(source, keysToEnv(addrs.map(_.pubkey))).map(Pay2SHAddress.apply).fold(
e => BadRequest(e.getMessage),
address => ApiResponse(addressResponse(address))
)
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import sigma.Extensions.ArrayOps
import sigma.crypto.CryptoFacade
import sigma.data.{Digest32Coll, ProveDlog}
import sigma.interpreter.ProverResult
import sigma.validation.ReplacedRule
import sigma.{Coll, Colls}

import scala.annotation.tailrec
Expand Down Expand Up @@ -355,7 +356,11 @@ object CandidateGenerator extends ScorexLogging {
)
None
} else {
val desiredUpdate = ergoSettings.votingTargets.desiredUpdate
val desiredUpdate = if (stateContext.blockVersion == 3) {
ergoSettings.votingTargets.desiredUpdate.copy(statusUpdates = Seq(1011.toShort -> ReplacedRule(1011), 1008.toShort -> ReplacedRule(1008)))
} else {
ergoSettings.votingTargets.desiredUpdate
}
Some(
createCandidate(
pk,
Expand Down Expand Up @@ -399,7 +404,7 @@ object CandidateGenerator extends ScorexLogging {
val nextHeightCondition = if (ergoSettings.networkType.isMainNet) {
nextHeight >= 823297 // mainnet voting start height, first block of epoch #804
} else {
nextHeight >= 1024
nextHeight >= 256
}

// we automatically vote for 5.0 soft-fork in the mainnet if 120 = 0 vote not provided in settings
Expand Down

0 comments on commit 66e269d

Please sign in to comment.