Skip to content

Commit

Permalink
ChainSettings used in ErgoStateContext, not ErgoSettings
Browse files Browse the repository at this point in the history
  • Loading branch information
kushti committed Nov 15, 2023
1 parent 280b3fe commit 2e9897d
Show file tree
Hide file tree
Showing 20 changed files with 65 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ object TransactionExecutionBenchmark extends HistoryTestHelpers with NVBenchmark
val boxes = bh.boxes
def bench: Long =
Utils.time {
assert(ErgoState.execTransactions(txs, emptyStateContext)(id => Try(boxes(ByteArrayWrapper(id)))) == Valid(178665000))
assert(ErgoState.execTransactions(txs, emptyStateContext, settings.nodeSettings)(id => Try(boxes(ByteArrayWrapper(id)))) == Valid(178665000))
}.toLong

(0 to WarmupRuns).foreach(_ => bench)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ object CandidateGenerator extends ScorexLogging {
stateContext: ErgoStateContext,
assets: Coll[(TokenId, Long)] = Colls.emptyColl
): Seq[ErgoTransaction] = {
val chainSettings = stateContext.ergoSettings.chainSettings
val chainSettings = stateContext.chainSettings
val propositionBytes = chainSettings.monetary.feePropositionBytes
val emission = chainSettings.emissionRules

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ case class ErgoTransaction(override val inputs: IndexedSeq[Input],
stateContext: ErgoStateContext): Try[Unit] = {
val res: Try[Unit] = Try {

lazy val reemissionSettings = stateContext.ergoSettings.chainSettings.reemission
lazy val reemissionSettings = stateContext.chainSettings.reemission
lazy val reemissionRules = reemissionSettings.reemissionRules

lazy val reemissionTokenId = ModifierId @@@ reemissionSettings.reemissionTokenId
Expand All @@ -234,7 +234,7 @@ case class ErgoTransaction(override val inputs: IndexedSeq[Input],
lazy val emissionNftId = ModifierId @@@ reemissionSettings.emissionNftId
lazy val emissionNftIdBytes = reemissionSettings.emissionNftIdBytes

lazy val chainSettings = stateContext.ergoSettings.chainSettings
lazy val chainSettings = stateContext.chainSettings
lazy val emissionRules = chainSettings.emissionRules

lazy val height = stateContext.currentHeight
Expand Down Expand Up @@ -436,7 +436,7 @@ case class ErgoTransaction(override val inputs: IndexedSeq[Input],
val currentTxCost = validation.result.payload.get
verifyInput(validation, boxesToSpend, dataBoxes, box, idx.toShort, stateContext, currentTxCost)
}
.validate(txReemission, !stateContext.ergoSettings.chainSettings.reemission.checkReemissionRules ||
.validate(txReemission, !stateContext.chainSettings.reemission.checkReemissionRules ||
verifyReemissionSpending(boxesToSpend, outputCandidates, stateContext).isSuccess, InvalidModifier(id, id, modifierTypeId))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ abstract class ErgoNodeViewHolder[State <: ErgoState[State]](settings: ErgoSetti

val recoveredStateTry = firstExtensionOpt
.fold[Try[ErgoStateContext]](Failure(new Exception("Could not find extension to recover from"))
)(ext => ErgoStateContext.recover(settings.chainSettings.genesisStateDigest, ext, lastHeaders)(settings))
)(ext => ErgoStateContext.recover(settings.chainSettings.genesisStateDigest, ext, lastHeaders)(settings.chainSettings))
.flatMap { ctx =>
val recoverVersion = idToVersion(lastHeaders.last.id)
val recoverRoot = bestFullBlock.header.stateRoot
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class DigestState protected(override val version: VersionTag,
.fold[Try[ErgoBox]](Failure(new Exception(s"Box with id ${Algos.encode(id)} not found")))(Success(_))
}

ErgoState.execTransactions(transactions, currentStateContext)(checkBoxExistence)
ErgoState.execTransactions(transactions, currentStateContext, nodeSettings)(checkBoxExistence)
.toTry
.map(_ => ())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import org.ergoplatform.modifiers.state.StateChanges
import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedModifier
import org.ergoplatform.nodeView.history.ErgoHistory
import org.ergoplatform.settings.ValidationRules._
import org.ergoplatform.settings.{ChainSettings, Constants, ErgoSettings, LaunchParameters}
import org.ergoplatform.settings.{ChainSettings, Constants, ErgoSettings, LaunchParameters, NodeConfigurationSettings}
import org.ergoplatform.wallet.interpreter.ErgoInterpreter
import scorex.core.validation.ValidationResult.Valid
import scorex.core.validation.{ModifierValidator, ValidationResult}
Expand Down Expand Up @@ -103,7 +103,8 @@ object ErgoState extends ScorexLogging {
* @return Result of transactions execution with total cost inside
*/
def execTransactions(transactions: Seq[ErgoTransaction],
currentStateContext: ErgoStateContext)
currentStateContext: ErgoStateContext,
nodeSettings: NodeConfigurationSettings)
(checkBoxExistence: ErgoBox.BoxId => Try[ErgoBox]): ValidationResult[Long] = {
val verifier: ErgoInterpreter = ErgoInterpreter(currentStateContext.currentParameters)

Expand All @@ -130,7 +131,7 @@ object ErgoState extends ScorexLogging {
}
}

val checkpointHeight = currentStateContext.ergoSettings.nodeSettings.checkpoint.map(_.height).getOrElse(0)
val checkpointHeight = nodeSettings.checkpoint.map(_.height).getOrElse(0)
if (currentStateContext.currentHeight <= checkpointHeight) {
Valid(0L)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ case class UpcomingStateContext(override val lastHeaders: Seq[Header],
override val genesisStateDigest: ADDigest,
override val currentParameters: Parameters,
override val validationSettings: ErgoValidationSettings,
override val votingData: VotingData)(implicit ergoSettings: ErgoSettings)
override val votingData: VotingData)(implicit chainSettings: ChainSettings)
extends ErgoStateContext(lastHeaders, lastExtensionOpt, genesisStateDigest, currentParameters,
validationSettings, votingData)(ergoSettings) {
validationSettings, votingData)(chainSettings) {

override def sigmaPreHeader: sigma.PreHeader = PreHeader.toSigma(predictedHeader)

Expand Down Expand Up @@ -65,16 +65,16 @@ class ErgoStateContext(val lastHeaders: Seq[Header],
val currentParameters: Parameters,
val validationSettings: ErgoValidationSettings,
val votingData: VotingData)
(implicit val ergoSettings: ErgoSettings)
(implicit val chainSettings: ChainSettings)
extends BlockchainStateContext
with BytesSerializable
with ScorexEncoding
with ScorexLogging {

override type M = ErgoStateContext

private val votingSettings = ergoSettings.chainSettings.voting
private val popowAlgos = new NipopowAlgos(ergoSettings.chainSettings)
private val votingSettings = chainSettings.voting
private val popowAlgos = new NipopowAlgos(chainSettings)

override def sigmaPreHeader: sigma.PreHeader =
PreHeader.toSigma(lastHeaders.headOption.getOrElse(PreHeader.fake))
Expand Down Expand Up @@ -107,7 +107,7 @@ class ErgoStateContext(val lastHeaders: Seq[Header],

def lastHeaderOpt: Option[Header] = lastHeaders.headOption

override def serializer: ErgoSerializer[M] = ErgoStateContextSerializer(ergoSettings)
override def serializer: ErgoSerializer[M] = ErgoStateContextSerializer(chainSettings)

/**
* @return state context corresponding to a block after last known one with fields provided
Expand All @@ -134,7 +134,7 @@ class ErgoStateContext(val lastHeaders: Seq[Header],
def simplifiedUpcoming(): UpcomingStateContext = {
val minerPk = org.ergoplatform.mining.group.generator
val version = lastHeaderOpt.map(_.version).getOrElse(Header.InitialVersion)
val nBits = lastHeaderOpt.map(_.nBits).getOrElse(ergoSettings.chainSettings.initialNBits)
val nBits = lastHeaderOpt.map(_.nBits).getOrElse(chainSettings.initialNBits)
val timestamp = lastHeaderOpt.map(_.timestamp + 1).getOrElse(System.currentTimeMillis())
val votes = Array.emptyByteArray
val proposedUpdate = ErgoValidationSettingsUpdate.empty
Expand Down Expand Up @@ -227,14 +227,14 @@ class ErgoStateContext(val lastHeaders: Seq[Header],
val proposedVotes = votes.map(_ -> 1)
val newVoting = VotingData(proposedVotes)
new ErgoStateContext(newHeaders, extensionOpt, genesisStateDigest, params,
extractedValidationSettings, newVoting)(ergoSettings)
extractedValidationSettings, newVoting)(chainSettings)
}
case _ =>
val newVotes = votes
val newVotingResults = newVotes.foldLeft(votingData) { case (v, id) => v.update(id) }
state.result.toTry.map { _ =>
new ErgoStateContext(newHeaders, extensionOpt, genesisStateDigest, currentParameters, validationSettings,
newVotingResults)(ergoSettings)
newVotingResults)(chainSettings)
}
}
}.flatten
Expand Down Expand Up @@ -332,16 +332,16 @@ object ErgoStateContext {
*/
val eip27Vote: Byte = 8

def empty(settings: ErgoSettings, parameters: Parameters): ErgoStateContext = {
empty(settings.chainSettings.genesisStateDigest, settings, parameters)
def empty(chainSettings: ChainSettings, parameters: Parameters): ErgoStateContext = {
empty(chainSettings.genesisStateDigest, chainSettings, parameters)
}

/**
* Initialize empty state context
*/
def empty(genesisStateDigest: ADDigest, settings: ErgoSettings, parameters: Parameters): ErgoStateContext = {
def empty(genesisStateDigest: ADDigest, chainSettings: ChainSettings, parameters: Parameters): ErgoStateContext = {
new ErgoStateContext(Seq.empty, None, genesisStateDigest, parameters, ErgoValidationSettings.initial,
VotingData.empty)(settings)
VotingData.empty)(chainSettings)
}

/**
Expand All @@ -352,14 +352,14 @@ object ErgoStateContext {
def recover(genesisStateDigest: ADDigest,
extension: Extension,
lastHeaders: Seq[Header])
(settings: ErgoSettings): Try[ErgoStateContext] = {
val vs = settings.chainSettings.voting
(chainSettings: ChainSettings): Try[ErgoStateContext] = {
val vs = chainSettings.voting
if (lastHeaders.lastOption.exists(_.height % vs.votingLength == 0)) {
val currentHeader = lastHeaders.last
Parameters.parseExtension(currentHeader.height, extension).flatMap { params =>
ErgoValidationSettings.parseExtension(extension).map { validationSettings =>
new ErgoStateContext(lastHeaders.reverse, Some(extension), genesisStateDigest, params,
validationSettings, VotingData.empty)(settings)
validationSettings, VotingData.empty)(chainSettings)
}
}
} else {
Expand All @@ -369,7 +369,7 @@ object ErgoStateContext {

}

case class ErgoStateContextSerializer(ergoSettings: ErgoSettings) extends ErgoSerializer[ErgoStateContext] {
case class ErgoStateContextSerializer(chainSettings: ChainSettings) extends ErgoSerializer[ErgoStateContext] {

private val Eip27SupportValue = 100 // see comment in serialize()

Expand Down Expand Up @@ -413,7 +413,7 @@ case class ErgoStateContextSerializer(ergoSettings: ErgoSettings) extends ErgoSe
}

new ErgoStateContext(lastHeaders, lastExtensionOpt, genesisDigest, params, validationSettings,
votingData)(ergoSettings)
votingData)(chainSettings)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ object ErgoStateReader extends ScorexLogging {
*/
def storageStateContext(store: LDBVersionedStore, settings: ErgoSettings): ErgoStateContext = {
store.get(ErgoStateReader.ContextKey)
.flatMap(b => ErgoStateContextSerializer(settings).parseBytesTry(b).toOption)
.flatMap(b => ErgoStateContextSerializer(settings.chainSettings).parseBytesTry(b).toOption)
.getOrElse {
log.warn("Can't read blockchain parameters from database")
ErgoStateContext.empty(settings, LaunchParameters)
ErgoStateContext.empty(settings.chainSettings, LaunchParameters)
}
}

Expand All @@ -94,13 +94,13 @@ object ErgoStateReader extends ScorexLogging {
if (lastHeaders.size != Constants.LastHeadersInContext) {
Failure(new Exception(s"Only ${lastHeaders.size} headers found in reconstructStateContextBeforeEpoch"))
} else {
val empty = ErgoStateContext.empty(settings, LaunchParameters)
val empty = ErgoStateContext.empty(settings.chainSettings, LaunchParameters)
val esc = new ErgoStateContext( lastHeaders,
None,
empty.genesisStateDigest,
empty.currentParameters,
empty.validationSettings,
empty.votingData)(settings)
empty.votingData)(settings.chainSettings)
Success(esc)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class UtxoState(override val persistentProver: PersistentBatchAVLProver[Digest32
.orElse(boxById(id))
.fold[Try[ErgoBox]](Failure(new Exception(s"Box with id ${Algos.encode(id)} not found")))(Success(_))

val txProcessing = ErgoState.execTransactions(transactions, currentStateContext)(checkBoxExistence)
val txProcessing = ErgoState.execTransactions(transactions, currentStateContext, ergoSettings.nodeSettings)(checkBoxExistence)
if (txProcessing.isValid) {
log.debug(s"Cost of block $headerId (${currentStateContext.currentHeight}): ${txProcessing.payload.getOrElse(0)}")
val blockOpsTry = ErgoState.stateChanges(transactions).flatMap { stateChanges =>
Expand Down Expand Up @@ -192,7 +192,7 @@ class UtxoState(override val persistentProver: PersistentBatchAVLProver[Digest32
}

if (fb.adProofs.isEmpty) {
if (fb.height >= estimatedTip.getOrElse(Int.MaxValue) - stateContext.ergoSettings.nodeSettings.adProofsSuffixLength) {
if (fb.height >= estimatedTip.getOrElse(Int.MaxValue) - ergoSettings.nodeSettings.adProofsSuffixLength) {
val adProofs = ADProofs(fb.header.id, proofBytes)
generate(LocallyGeneratedModifier(adProofs))
}
Expand Down Expand Up @@ -309,7 +309,7 @@ object UtxoState {

val store = new LDBVersionedStore(dir, initialKeepVersions = settings.nodeSettings.keepVersions)

val defaultStateContext = ErgoStateContext.empty(settings, parameters)
val defaultStateContext = ErgoStateContext.empty(settings.chainSettings, parameters)
val storage = new VersionedLDBAVLStorage(store)
val persistentProver = PersistentBatchAVLProver.create(
p,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ final class WalletStorage(store: LDBKVStore, settings: ErgoSettings) extends Sco
def readStateContext(parameters: Parameters): ErgoStateContext = {
cachedStateContext = Some(store
.get(StateContextKey)
.flatMap(r => ErgoStateContextSerializer(settings).parseBytesTry(r).toOption)
.getOrElse(ErgoStateContext.empty(settings, parameters))
.flatMap(r => ErgoStateContextSerializer(settings.chainSettings).parseBytesTry(r).toOption)
.getOrElse(ErgoStateContext.empty(settings.chainSettings, parameters))
)
cachedStateContext.get
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ class CandidateGeneratorPropSpec extends ErgoPropertyTest {

val ms = MonetarySettings(minerRewardDelay = delta)
val st = settings.copy(chainSettings = settings.chainSettings.copy(monetary = ms))
val sc = ErgoStateContext.empty(genesisStateDigest, st, parameters)
val sc = ErgoStateContext.empty(genesisStateDigest, st.chainSettings, parameters)
val txBoxes = bh.boxes.grouped(inputsNum).map(_.values.toIndexedSeq).toSeq

val blockTx =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ class ErgoTransactionSpec extends ErgoPropertyTest with ErgoTestConstants {
val maxCost = (Int.MaxValue - 10) / 10 // cannot use Int.MaxValue directly due to overflow when it is converted to block cost
val ps = Parameters(0, DefaultParameters.updated(MaxBlockCostIncrease, maxCost), emptyVSUpdate)
val sc = new ErgoStateContext(Seq.empty, None, genesisStateDigest, ps, ErgoValidationSettings.initial,
VotingData.empty)(settings)
VotingData.empty)(settings.chainSettings)
.upcoming(org.ergoplatform.mining.group.generator,
0L,
settings.chainSettings.initialNBits,
Expand Down Expand Up @@ -478,7 +478,7 @@ class ErgoTransactionSpec extends ErgoPropertyTest with ErgoTestConstants {
LaunchParameters.parametersTable.updated(Parameters.BlockVersion, blockVersion),
LaunchParameters.proposedUpdate)
new ErgoStateContext(Seq(header), None, genesisStateDigest, params, ErgoValidationSettings.initial,
VotingData.empty)(settings)
VotingData.empty)(settings.chainSettings)
}

def stateContextForTx(tx: ErgoTransaction, blockVersion: Byte): ErgoStateContext = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class ExpirationSpecification extends ErgoPropertyTest {

val updContext = {
val inContext = new ErgoStateContext(Seq(fakeHeader), None, genesisStateDigest, parameters, validationSettingsNoIl,
VotingData.empty)(settings)
VotingData.empty)(settings.chainSettings)
inContext.appendFullBlock(fb).get
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,29 +162,31 @@ class ErgoStateSpecification extends ErgoPropertyTest {
val stateContext = emptyStateContext
val expectedCost = 185160

val nodeSettings = settings.nodeSettings

// successful validation
ErgoState.execTransactions(txs, stateContext)(id => Try(boxes(ByteArrayWrapper(id)))) shouldBe Valid(expectedCost)
ErgoState.execTransactions(txs, stateContext, nodeSettings)(id => Try(boxes(ByteArrayWrapper(id)))) shouldBe Valid(expectedCost)

// cost limit exception expected when crossing MaxBlockCost
val tooManyTxs = (1 to 10).flatMap(_ => generateTxs)
assert(
ErgoState.execTransactions(tooManyTxs, stateContext)(id => Try(boxes(ByteArrayWrapper(id)))).errors.head.message.contains(
ErgoState.execTransactions(tooManyTxs, stateContext, nodeSettings)(id => Try(boxes(ByteArrayWrapper(id)))).errors.head.message.contains(
"Accumulated cost of block transactions should not exceed <maxBlockCost>"
)
)

// missing box in state
ErgoState.execTransactions(txs, stateContext)(_ => Failure(new RuntimeException)).errors.head.message shouldBe
ErgoState.execTransactions(txs, stateContext, nodeSettings)(_ => Failure(new RuntimeException)).errors.head.message shouldBe
"Every input of the transaction should be in UTXO. null"

// tx validation should kick in and detect block height violation
val invalidTx = invalidErgoTransactionGen.sample.get
assert(
ErgoState.execTransactions(txs :+ invalidTx, stateContext)(id => Try(boxes.getOrElse(ByteArrayWrapper(id), invalidTx.outputs.head)))
ErgoState.execTransactions(txs :+ invalidTx, stateContext, nodeSettings)(id => Try(boxes.getOrElse(ByteArrayWrapper(id), invalidTx.outputs.head)))
.errors.head.message.startsWith("Transaction outputs should have creationHeight not exceeding block height.")
)

// no transactions are valid
assert(ErgoState.execTransactions(Seq.empty, stateContext)(id => Try(boxes(ByteArrayWrapper(id)))).isValid)
assert(ErgoState.execTransactions(Seq.empty, stateContext, nodeSettings)(id => Try(boxes(ByteArrayWrapper(id)))).isValid)
}
}
Loading

0 comments on commit 2e9897d

Please sign in to comment.