Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
1e262e0
version set to 6.0.4
kushti Jan 28, 2026
d5f4093
chatgpt plugin removed
kushti Mar 9, 2026
351b1d2
Remove incorrect security annotations from public mining and script A…
jozanek May 21, 2026
8133222
Merge branch 'envs-improvs' of github.com:ergoplatform/ergo into v6.0.4
kushti May 26, 2026
3244892
Speed up integration tests and fix Docker Desktop compatibility
jozanek May 30, 2026
2782c74
merging v6.0.4
kushti Jun 7, 2026
9dd7f10
Merge pull request #2298 from ergoplatform/openapi-ai-removed
kushti Jun 7, 2026
98e74e3
Merge branch 'v6.0.3' of github.com:ergoplatform/ergo into v6.0.4
kushti Jun 7, 2026
81e0502
Merge branch 'v6.0.4' of github.com:ergoplatform/ergo into v6.0.4
kushti Jun 7, 2026
0f2f5be
Add Inv -> RequestModifier test to ErgoNodeViewSynchronizerSpecificat…
Ergologica Jun 11, 2026
7b394cc
Validate NiPoPoW proof parameters
tum231990 Jun 12, 2026
639ddd8
Validate wallet scan id route parameters
tum231990 Jun 12, 2026
688750f
fix: validate REST modifier id length
tum231990 Jun 12, 2026
1d4d1da
fix: validate transaction route id lengths
tum231990 Jun 12, 2026
dfec320
fix: reject invalid secret proof hex
tum231990 Jun 12, 2026
d663f89
fix: enforce chain slice range limit
tum231990 Jun 12, 2026
204d11c
Remove CLAUDE.md reference from build.sbt comment
jozanek Jun 13, 2026
4638278
Merge pull request #2401 from a-shannon/fix/chain-slice-range-limit
kushti Jun 15, 2026
85136c7
Merge pull request #2383 from a-shannon/fix/wallet-scan-id-validation
kushti Jun 16, 2026
21c327f
Address NiPoPoW params review feedback
Jun 16, 2026
85f2c4b
Merge pull request #2387 from a-shannon/fix/validate-modifier-id-length
kushti Jun 19, 2026
a2ffb6e
Stabilize fee estimation heuristics
Jun 19, 2026
2a7c0fb
Merge pull request #2388 from a-shannon/fix/validate-transaction-rout…
kushti Jun 20, 2026
b5ea1e2
Merge pull request #2391 from a-shannon/fix/reject-invalid-hint-proof…
kushti Jun 20, 2026
f622d73
Merge pull request #2376 from Ergologica/test/inv-requestmodifier-2184
kushti Jun 21, 2026
3444d58
Merge pull request #2323 from jozanek/fix-swagger-authorization
kushti Jun 23, 2026
cbd885b
Merge origin/v6.0.4 into optimize-it
jozanek Jul 4, 2026
e4fb82f
Remove unused ContentTypes import in InfoApiRoute
jozanek Jul 4, 2026
da363e8
Merge branch 'master' of github.com:ergoplatform/ergo into v6.0.4
kushti Jul 8, 2026
f89dcbf
Merge branch 'v6.0.4' of github.com:ergoplatform/ergo into v6.0.4
kushti Jul 8, 2026
b91bc67
Merge branch 'v6.0.4' into optimize-it
kushti Jul 8, 2026
be0d857
Merge pull request #2344 from jozanek/optimize-it
kushti Jul 8, 2026
4777818
6.0.5 version set
kushti Jul 8, 2026
a3ac58d
reverting concurrentRestrictions to master
kushti Jul 9, 2026
17f578a
Merge pull request #2379 from a-shannon/fix/nipopow-proof-param-bounds
kushti Jul 10, 2026
366a046
Validate NiPoPoW proof header PoW
tum231990 Jul 10, 2026
594eeb9
Remove unused InfoApiRoute import
tum231990 Jul 10, 2026
cdd89ce
Merge pull request #2396 from a-shannon/fix/nipopow-validated-pow-levels
kushti Jul 13, 2026
ce1dfac
Merge pull request #2410 from a-shannon/fix/fee-estimation-stability
kushti Jul 13, 2026
706a916
Reject invalid inbound NiPoPoW parameters
tum231990 Jul 13, 2026
3cc7f3c
refactor: reuse NiPoPoW parameter validation
Jul 13, 2026
28d644a
Merge pull request #2417 from a-shannon/codex/fix-nipopow-inbound-params
kushti Jul 14, 2026
14e7e71
Bound per-peer outbound buffering
tum231990 Jul 14, 2026
eaa7f1b
Close all live connections for blacklisted IPs
tum231990 Jul 14, 2026
b7baa6c
Preserve asset issuance with token burn requests
tum231990 Jul 15, 2026
83b15cc
Merge pull request #2430 from a-shannon/fix/burn-issue-output-matching
kushti Jul 15, 2026
514800b
Test outbound retry accounting through ACK flow
tum231990 Jul 15, 2026
130518a
Merge pull request #2426 from a-shannon/fix/p2p-outbound-buffer-limit
kushti Jul 15, 2026
84b1638
Merge pull request #2427 from a-shannon/fix/blacklisted-ip-connection…
kushti Jul 15, 2026
e9cb942
test: reproduce reconvergent mempool duplicate ids
a-shannon Jul 20, 2026
7f8218f
fix: prevent duplicate ids in ordered tx pool
a-shannon Jul 20, 2026
cdde03d
Merge pull request #2439 from a-shannon/fix/ordered-tx-pool-duplicate…
kushti Jul 20, 2026
dc22b0b
Fix extra indexer ordering across reorgs
a-shannon Jul 20, 2026
1172a8f
Track extra index tip across reorgs
a-shannon Jul 21, 2026
dbab2d1
Fix indentation in openapi.yaml for CommitmentWithSecret
zargarzadehm Jul 22, 2026
266c2c6
Merge pull request #2445 from ergoplatform/fix-openapi-indentation
kushti Jul 22, 2026
de722ce
candidate block generation improvements
kushti Jul 22, 2026
c8814ec
more tests
kushti Jul 23, 2026
093b152
Merge pull request #2448 from ergoplatform/cand-improvements
kushti Jul 23, 2026
aec2bdd
Merge branch 'v6.0.4' into fix/extra-indexer-reorg-ordering
kushti Jul 28, 2026
e11133c
Merge pull request #2442 from a-shannon/fix/extra-indexer-reorg-ordering
kushti Jul 28, 2026
0c05936
fixing ExtraIndexerSpec
kushti Jul 30, 2026
88fdaf7
Merge branch 'v6.0.4' of github.com:ergoplatform/ergo into v6.0.5
kushti Jul 30, 2026
7589493
Merge branch 'v6.0.5' of github.com:ergoplatform/ergo into v6.0.5
kushti Jul 30, 2026
e027c73
Log API queries at DEBUG level
Ergologica Aug 2, 2026
e5844b1
Document the API query logger in logback.xml
Ergologica Aug 2, 2026
bd6991d
Add spec covering the API query logger
Ergologica Aug 2, 2026
ea00db7
Merge pull request #2456 from Ergologica/feature/log-api-queries-1909
kushti Aug 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 17 additions & 21 deletions do-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,26 @@ if [[ $conf_version != $jar_version ]]; then
exit 1
fi

openapi_files=("openapi.yaml" "openapi-ai.yaml")
openapi_path="src/main/resources/api/openapi.yaml"
version_line=$(grep 'version:' "$openapi_path")

for file in "${openapi_files[@]}"; do
openapi_path="src/main/resources/api/$file"
version_line=$(grep 'version:' "$openapi_path")

if [[ -z $version_line ]]; then
echo "Error: Version line not found in $openapi_path"
exit 1
fi
if [[ -z $version_line ]]; then
echo "Error: Version line not found in $openapi_path"
exit 1
fi

actual_version=$(echo $version_line | awk -F '"' '{print $2}')
actual_version=$(echo $version_line | awk -F '"' '{print $2}')

if [[ -z $actual_version ]]; then
echo "Error: Version not found in $openapi_path"
exit 1
fi
if [[ -z $actual_version ]]; then
echo "Error: Version not found in $openapi_path"
exit 1
fi

if [[ $actual_version != $jar_version ]]; then
echo "Version mismatch in $openapi_path: ($actual_version) != jar ($jar_version)."
echo "Removing jar $jar"
rm "$jar"
exit 1
fi
done
if [[ $actual_version != $jar_version ]]; then
echo "Version mismatch in $openapi_path: ($actual_version) != jar ($jar_version)."
echo "Removing jar $jar"
rm "$jar"
exit 1
fi

echo "do-release completed successfully"
22 changes: 18 additions & 4 deletions ergo-core/src/main/scala/org/ergoplatform/http/api/ApiCodecs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ trait ApiCodecs extends JsonCodecs {
fromTry(validationResult.toTry)
}

private def fromTryAt[T](value: Try[T], cursor: ACursor): Decoder.Result[T] = value match {
case Success(result) => Right(result)
case Failure(e) => Left(DecodingFailure.fromThrowable(e, cursor.history))
}

private def decodeBase16(value: String, cursor: ACursor): Decoder.Result[Array[Byte]] =
fromTryAt(Base16.decode(value), cursor)

implicit val leafDataEncoder: Encoder[LeafData] = Encoder.instance(xs => Base16.encode(xs).asJson)

implicit val digestEncoder: Encoder[Digest] = Encoder.instance(x => Base16.encode(x).asJson)
Expand Down Expand Up @@ -338,11 +346,14 @@ trait ApiCodecs extends JsonCodecs {
pubkey <- c.downField("pubkey").as[SigmaLeaf]
proof <- c.downField("proof").as[String]
position <- c.downField("position").as[NodePosition]
challengeBytes <- decodeBase16(challenge, c.downField("challenge"))
proofBytes <- decodeBase16(proof, c.downField("proof"))
proofTree <- fromTryAt(Try(SigSerializer.parseAndComputeChallenges(pubkey, proofBytes)(null)), c.downField("proof"))
} yield
RealSecretProof(
pubkey,
Challenge @@ Base16.decode(challenge).get.toColl,
SigSerializer.parseAndComputeChallenges(pubkey, Base16.decode(proof).get)(null),
Challenge @@ challengeBytes.toColl,
proofTree,
position
)
case h: String if h == "proofSimulated" =>
Expand All @@ -351,11 +362,14 @@ trait ApiCodecs extends JsonCodecs {
pubkey <- c.downField("pubkey").as[SigmaLeaf]
proof <- c.downField("proof").as[String]
position <- c.downField("position").as[NodePosition]
challengeBytes <- decodeBase16(challenge, c.downField("challenge"))
proofBytes <- decodeBase16(proof, c.downField("proof"))
proofTree <- fromTryAt(Try(SigSerializer.parseAndComputeChallenges(pubkey, proofBytes)(null)), c.downField("proof"))
} yield
SimulatedSecretProof(
pubkey,
Challenge @@ Base16.decode(challenge).get.toColl,
SigSerializer.parseAndComputeChallenges(pubkey, Base16.decode(proof).get)(null),
Challenge @@ challengeBytes.toColl,
proofTree,
position
)
case _ =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ class NipopowAlgos(val chainSettings: ChainSettings) {
Int.MaxValue
}

def hasValidPow(header: Header): Boolean = powScheme.validate(header).isSuccess

/**
* Computes best score of a given chain.
* The score value depends on number of µ-superblocks in the given chain.
Expand All @@ -96,6 +98,8 @@ class NipopowAlgos(val chainSettings: ChainSettings) {
* end function
*/
def bestArg(chain: Seq[Header])(m: Int): Int = {
require(m >= 1, s"$m < 1")

@scala.annotation.tailrec
def loop(level: Int, acc: Seq[(Int, Int)] = Seq.empty): Seq[(Int, Int)] =
if (level == 0) {
Expand Down Expand Up @@ -130,7 +134,6 @@ class NipopowAlgos(val chainSettings: ChainSettings) {
val k = params.k
val m = params.m

require(params.k >= 1, s"$k < 1")
require(chain.lengthCompare(k + m) >= 0, s"Can not prove chain of size < ${k + m}")
require(chain.head.header.isGenesis, "Can not prove non-anchored chain")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ case class NipopowProof(popowAlgos: NipopowAlgos,
* @return true if the proof is valid
*/
lazy val isValid: Boolean = {
this.hasValidConnections && this.hasValidHeights && this.hasValidProofs && this.hasValidDifficultyHeaders
PoPowParams.isValid(m, k) &&
this.hasValidConnections &&
this.hasValidHeights &&
this.hasValidProofs &&
this.hasValidDifficultyHeaders &&
this.hasValidPow
}

/**
Expand Down Expand Up @@ -155,6 +160,8 @@ case class NipopowProof(popowAlgos: NipopowAlgos,
suffixHead.checkInterlinksProof()
}

lazy val hasValidPow: Boolean = headersChain.forall(popowAlgos.hasValidPow)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MINOR Validating every header's Autolykos PoW is the right fix, but isValid is evaluated inside ErgoNodeViewSynchronizer's receive (case Success(proof) if proof.isValid around line 1085 of ErgoNodeViewSynchronizer.scala), so a proof chain of hundreds of headers now runs full PoW verification on the synchronizer's dispatcher thread, stalling its mailbox during nipopow bootstrap — and several proofs can arrive back-to-back from the p2pNipopows peers.

Suggestion: run the proof validation in a Future on a dedicated dispatcher and pipeTo the result back, keeping the synchronizer responsive.


}

object NipopowProof {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.ergoplatform.modifiers.history.popow

import scala.util.Try

/**
* NiPoPoW proof params from the KMZ17 paper
*
Expand All @@ -12,5 +14,15 @@ package org.ergoplatform.modifiers.history.popow
* to the block header)
*
*/
case class PoPowParams(m: Int, k: Int, continuous: Boolean)
final class PoPowParams private (val m: Int, val k: Int, val continuous: Boolean, val minChainLength: Int)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MINOR: PoPowParams going from case class to a private-constructor class with apply returning Try is a source/binary break in ergo-core's public API (no more direct construction, copy, or unapply). Since ergo-core is the library SPV clients build against, this deserves an explicit entry in the 6.0.5 release notes.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MINOR minChainLength is not read anywhere in production code — its only consumer is the assertion in PoPowAlgosSpec. If it is groundwork for the follow-up NiPoPoW parsing work (#2461), fine to keep, but then a short comment saying so would help; otherwise it is a dead field that suggests a validation which does not actually happen yet.


object PoPowParams {
def isValid(m: Int, k: Int): Boolean =
m >= 1 && k >= 1 && m.toLong + k.toLong <= Int.MaxValue

def apply(m: Int, k: Int, continuous: Boolean): Try[PoPowParams] = Try {
require(isValid(m, k), s"Invalid NiPoPoW parameters: m=$m, k=$k")
new PoPowParams(m, k, continuous, m + k)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: minChainLength is computed and stored but never read in production code (only one test asserts it). Either drop it or use it in prove's chain.lengthCompare(k + m) check so it earns its place.

}
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.ergoplatform.serialization

import io.circe.syntax._
import io.circe.ACursor
import io.circe.{ACursor, Json}
import org.ergoplatform.ErgoBox
import org.ergoplatform.ErgoBox.{AdditionalRegisters, NonMandatoryRegisterId}
import org.ergoplatform.http.api.ApiCodecs
Expand All @@ -14,6 +14,9 @@ import org.ergoplatform.wallet.Constants.ScanId
import org.ergoplatform.wallet.boxes.TrackedBox
import cats.syntax.either._
import sigma.ast.{ErgoTree, EvaluatedValue, SType}
import sigmastate.interpreter.SecretProven

import scala.util.Try

class JsonSerializationCoreSpec extends ErgoCorePropertyTest
with ApiCodecs {
Expand Down Expand Up @@ -61,6 +64,26 @@ class JsonSerializationCoreSpec extends ErgoCorePropertyTest
}
}

property("secret proof decoder should reject invalid hex without throwing") {
val pubkey = proveDlogGen.sample.get
val pubkeyJson = Json.obj("op" -> pubkey.opCode.toByte.asJson, "h" -> pubkey.value.asJson)

Seq("zz" -> "00", "00" -> "zz").foreach { case (challenge, proof) =>
val json = Json.obj(
"hint" -> "proofReal".asJson,
"challenge" -> challenge.asJson,
"pubkey" -> pubkeyJson,
"proof" -> proof.asJson,
"position" -> "0".asJson
)

val decoded = Try(json.as[SecretProven])
decoded.isSuccess shouldBe true
decoded.get.isLeft shouldBe true
decoded.get.left.get.message.toLowerCase should include ("hex")
}
}

private def checkTrackedBox(c: ACursor, b: TrackedBox)(implicit opts: Detalization) = {
c.downField("spent").as[Boolean] shouldBe Right(b.spendingStatus.spent)
c.downField("onchain").as[Boolean] shouldBe Right(b.chainStatus.onChain)
Expand Down
3 changes: 3 additions & 0 deletions src/it/scala/org/ergoplatform/it/OpenApiSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class OpenApiSpec extends AnyFlatSpec with IntegrationSuite {
.withFallback(nodeSeedConfigs.head)
.withFallback(allowLocalConfig)

// `lazy` so the container is only started when a test actually touches `node`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: the lazy val change is right, but it documents that the only OpenAPI conformance test remains ignored (checker image gone) — so the openapi.yaml edits on this branch aren't machine-checked. Worth a tracking issue to restore an OpenAPI validation step.

// The single test below is currently `ignore`d (the openapi-checker image is gone),
// so without `lazy` we would start and tear down a node for nothing.
lazy val node: Node = docker.startDevNetNode(offlineGeneratingPeer).get

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MINOR The spec's only test remains ignored (the openapi-checker image is gone), so this suite passes CI while providing zero signal — the new comment documents the situation but keeps the dead spec. Consider deleting the spec or reviving the check with a maintained validator image.


def renderTemplate(template: String, varMapping: Map[String, String]): String =
Expand Down
18 changes: 0 additions & 18 deletions src/main/resources/.well-known/ai-plugin.json

This file was deleted.

Loading
Loading