Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
7b394cc
Validate NiPoPoW proof parameters
tum231990 Jun 12, 2026
21c327f
Address NiPoPoW params review feedback
Jun 16, 2026
a2ffb6e
Stabilize fee estimation heuristics
Jun 19, 2026
4777818
6.0.5 version set
kushti Jul 8, 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
0dc1a14
initial implementation of cap on peers db size
kushti Jul 24, 2026
3ee5bbf
more optimal algs
kushti Jul 28, 2026
c69c75e
optimization, SeenPeers limiting
kushti Jul 30, 2026
d2f2ee4
optimizations in loadPeers
kushti Jul 30, 2026
c8cf453
Merge branch 'v6.0.4' of github.com:ergoplatform/ergo into p2p-defense
kushti Jul 30, 2026
8eb8197
Merge branch 'v6.0.4' of github.com:ergoplatform/ergo into p2p-defense
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
ebe3dba
Merge branch 'v6.0.5' of github.com:ergoplatform/ergo into p2p-defense
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
804762e
Add review-requested test coverage for tx script failures and full-bl…
kushti Aug 18, 2026
4d93c8a
Fix ExtraIndexer checkpoint recovery
a-shannon Aug 12, 2026
ed971fa
refactor: tighten extra indexer test seams
a-shannon Aug 12, 2026
ac26b44
ci: rerun integration tests
a-shannon Aug 12, 2026
bcfe56b
fix: stop only ExtraIndexer on rollback failure
a-shannon Aug 12, 2026
02cfd04
Remove redundant block transaction filter
a-shannon Aug 16, 2026
572ca8e
Retrigger CI after DeepRollBackSpec timeout
a-shannon Aug 16, 2026
994e582
refactor: restore v6.0.5 ExtraIndexer history wiring
a-shannon Aug 19, 2026
93c9302
fix: keep deferred ExtraIndexer catch-up retry
a-shannon Aug 19, 2026
e3178cb
refactor: restore indexed contract template storage
a-shannon Aug 19, 2026
0f9862f
refactor: restore indexed address storage
a-shannon Aug 19, 2026
5d434e4
refactor: restore indexed token storage
a-shannon Aug 19, 2026
12b247e
refactor: restore v6.0.5 indexer state
a-shannon Aug 19, 2026
eb4118a
refactor: restore v6.0.5 history storage
a-shannon Aug 19, 2026
077985c
refactor: restore v6.0.5 full block processor
a-shannon Aug 19, 2026
02923ec
test: restore non-AD history specification
a-shannon Aug 19, 2026
8edecb1
test: restore ExtraIndexer chain generator
a-shannon Aug 19, 2026
a0e936e
test: keep deferred catch-up regression
a-shannon Aug 19, 2026
cfd6eae
test: keep deferred catch-up test seam
a-shannon Aug 19, 2026
af79298
test: restore history storage specification
a-shannon Aug 19, 2026
458af20
test: clarify deferred catch-up fixture
a-shannon Aug 19, 2026
4130b6b
Update comment for clarity on fork state
a-shannon Aug 19, 2026
4aa34ff
Merge branch 'master' of github.com:ergoplatform/ergo into v6.0.5
kushti Aug 21, 2026
fe8f2e4
Merge pull request #2476 from a-shannon/fix/extra-indexer-catch-up-retry
kushti Aug 21, 2026
5f0e92a
adressing review comments
kushti Aug 21, 2026
25ae315
scrypto updated to 3.1.1, sigmasdk to 6.0.6
Aug 21, 2026
211ca58
scala 2.13 and http-circe versions update
Aug 24, 2026
4c43f0e
deprecation messages fix
Aug 26, 2026
13e9283
Merge pull request #2489 from ergoplatform/additional-tests
kushti Aug 31, 2026
5528ef5
Merge pull request #2416 from ergoplatform/v6.0.5
kushti Aug 31, 2026
f0d623d
Merge branch 'master' of github.com:ergoplatform/ergo into p2p-defense
Sep 3, 2026
7db01c7
addressing review comments
Sep 3, 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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
scala: [2.13.16, 2.12.20, 2.11.12]
scala: [2.13.18, 2.12.20, 2.11.12]
java: [adopt@1.8]
runs-on: ${{ matrix.os }}
steps:
Expand Down Expand Up @@ -64,7 +64,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
scala: [2.13.16, 2.12.20, 2.11.12]
scala: [2.13.18, 2.12.20, 2.11.12]
java: [adopt@1.8]
runs-on: ${{ matrix.os }}
steps:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ devnet
.ensime
.ensime_cache/
scorex.yaml
*.iml

# LLM reports on code analysis etc
llm_generated
Expand Down
4 changes: 2 additions & 2 deletions avldb/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import sbt.Keys.testFrameworks

val scala211 = "2.11.12"
val scala212 = "2.12.20"
val scala213 = "2.13.16"
val scala213 = "2.13.18"

name := "avldb"

Expand Down Expand Up @@ -30,7 +30,7 @@ val Versions = new {
libraryDependencies ++= Seq(
"ch.qos.logback" % "logback-classic" % "1.2.13",
"com.google.guava" % "guava" % "23.0",
"org.scorexfoundation" %% "scrypto" % "2.3.0",
"org.scorexfoundation" %% "scrypto" % "3.1.1",
"org.scalatest" %% "scalatest" % "3.2.19" % Test,
"org.scalacheck" %% "scalacheck" % Versions.scalacheck(scalaVersion.value) % Test,
Versions.scalatestplus(scalaVersion.value),
Expand Down
8 changes: 4 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ logLevel := Level.Debug
// this values should be in sync with ergo-wallet/build.sbt
val scala211 = "2.11.12"
val scala212 = "2.12.20"
val scala213 = "2.13.16"
val scala213 = "2.13.18"

lazy val commonSettings = Seq(
organization := "org.ergoplatform",
Expand Down Expand Up @@ -39,11 +39,11 @@ lazy val commonSettings = Seq(

publishArtifact in (Compile, packageDoc) := false

val circeVersion = "0.13.0"
val circeVersion = "0.14.15"
val akkaVersion = "2.6.10"
val akkaHttpVersion = "10.2.4"

val sigmaStateVersion = "6.0.3"
val sigmaStateVersion = "6.0.6"
val ficusVersion = "1.4.7"

// for testing current sigmastate build (see sigmastate-ergo-it jenkins job)
Expand Down Expand Up @@ -336,7 +336,7 @@ lazy val ergo = (project in file("."))
"com.github.scopt" %% "scopt" % "4.1.0",

// API dependencies
"de.heikoseeberger" %% "akka-http-circe" % "1.20.0",
"de.heikoseeberger" %% "akka-http-circe" % "1.39.2",

// app dependencies
// jaxb-api is included only to avoid a runtime exception
Expand Down
8 changes: 4 additions & 4 deletions ergo-core/build.sbt
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// this values should be in sync with root (i.e. ../build.sbt)
val scala211 = "2.11.12"
val scala212 = "2.12.20"
val scala213 = "2.13.16"
val scala213 = "2.13.18"

val deps211 = Seq(
"io.circe" %% "circe-core" % "0.10.0",
"io.circe" %% "circe-generic" % "0.10.0",
"io.circe" %% "circe-parser" % "0.10.0")
val deps212 = Seq(
"io.circe" %% "circe-core" % "0.13.0",
"io.circe" %% "circe-generic" % "0.13.0",
"io.circe" %% "circe-parser" % "0.13.0")
"io.circe" %% "circe-core" % "0.14.15",
"io.circe" %% "circe-generic" % "0.14.15",
"io.circe" %% "circe-parser" % "0.14.15")

publishMavenStyle := true
Test / publishArtifact := false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import scorex.crypto.authds.merkle.{BatchMerkleProof, Leaf, MerkleProof, MerkleT
import scorex.crypto.hash.Digest32
import scorex.util.ModifierId
import scala.annotation.nowarn
import scala.collection.mutable
/**
* Extension block section with header id not provided
*
Expand Down Expand Up @@ -49,9 +48,8 @@ class ExtensionCandidate(val fields: Seq[(Array[Byte], Array[Byte])]) {
val indices = keys.flatMap(key => fields.find(_._1 sameElements key)
.map(Extension.kvToLeaf)
.map(kv => Leaf[Digest32](LeafData @@ kv)(Algos.hash).hash)
.flatMap(leafData => interlinksMerkleTree.elementsHashIndex.get(
new mutable.WrappedArray.ofByte(leafData))))
if (indices.isEmpty) None else interlinksMerkleTree.proofByIndices(indices)(Algos.hash)
.flatMap(leafData => interlinksMerkleTree.indexByElementHash(leafData)))
if (indices.isEmpty) None else interlinksMerkleTree.proofByIndices(indices)
}
}

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)

}

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 @@ -10,7 +12,20 @@ package org.ergoplatform.modifiers.history.popow
* to calculate difficulty to be added to the proof). One-shot use means using the proof to just
* to prove that a best chain contains some header (e.g. to work with a transaction corresponding
* to the block header)
* @param minChainLength - minimal length of a proof's header chain acceptable for the params, always m + k.
* Kept as groundwork for the proof-length checks of the NiPoPoW parsing rework (#2461),
* not read by validation yet
*
*/
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)

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)
}
}

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

import org.ergoplatform.modifiers.mempool.{ErgoTransaction, ErgoTransactionSerializer}
import org.ergoplatform.settings.Constants.TrueTree
import org.ergoplatform.utils.ErgoCorePropertyTest
import org.ergoplatform.{ErgoBoxCandidate, Input}
import scorex.crypto.authds.ADKey
import scorex.util.encode.Base16
import sigma.ast.IntConstant
import sigma.interpreter.{ContextExtension, ProverResult}

import scala.util.Try

/**
* Pins the sigma-state 6.0.6 change "reject negative-id vars in ContextExtension
* deserializer" and documents its consensus impact.
*
* The wire format itself did not change: var ids are written as one raw byte via
* signed `put(id)` (verified against the published sources of both 6.0.3 and 6.0.6).
* What changed is the reader only: 6.0.6 adds an explicit
* "Negative id of context extension variable" guard, so transactions carrying such
* extensions now fail at parse time with a `SerializerException`.
*
* Before 6.0.6 the same transaction could still be serialized/parsed successfully;
* negative ids were rejected later, at proving/verification time, with different
* exceptions (e.g., `NegativeArraySizeException`, `ArrayIndexOutOfBoundsException`).
* Those paths are covered by `ErgoTransactionSpec`. This spec adds the missing
* serializer-level and transaction-parser-level coverage that directly answers the
* review's confirm-item.
*
* Consensus impact: a hand-crafted transaction with a negative extension id could,
* in principle, be mined by an un-upgraded node and rejected by upgraded nodes.
* All known wallets/SDKs use small non-negative var ids, so no such transactions
* are known; the change is a soft-fork-style tightening that is safe once the
* majority of hashrate is upgraded.
*/
class ContextExtensionSpec extends ErgoCorePropertyTest {

private val serializer = ContextExtension.serializer

property("ContextExtension deserialization rejects negative var id") {
// wire layout: [values count][id][serialized value]
val bytes = serializer.toBytes(ContextExtension(Map(56.toByte -> IntConstant(0))))
bytes(1) = 0xC8.toByte // id 56 -> -56 as signed byte
val parsed = Try(serializer.fromBytes(bytes))
parsed.isFailure shouldBe true
parsed.failed.get.getMessage.contains("Negative id") shouldBe true
}

property("ContextExtension serialization writes var id byte raw") {
// pins that the rejected wire bytes are producible by ordinary node code;
// the writer does not range-check the id
val bytes = serializer.toBytes(ContextExtension(Map((-56).toByte -> IntConstant(0))))
bytes(1) shouldBe 0xC8.toByte
}

property("ContextExtension valid ids round-trip") {
Seq(0.toByte, 127.toByte).foreach { id =>
val ce = ContextExtension(Map(id -> IntConstant(1)))
serializer.fromBytes(serializer.toBytes(ce)) shouldBe ce
}
}

property("ErgoTransaction parsing rejects negative context extension var id") {
val boxId = ADKey @@ Base16.decode("c95c2ccf55e03cac6659f71ca4df832d28e2375569cec178dcb17f3e2e5f7742").get
val input = Input(
boxId,
ProverResult(Array.emptyByteArray, ContextExtension(Map((-10).toByte -> IntConstant(0))))
)
val output = new ErgoBoxCandidate(1000000000L, TrueTree, 0)
val tx = ErgoTransaction(IndexedSeq(input), IndexedSeq.empty, IndexedSeq(output))

val bytes = ErgoTransactionSerializer.toBytes(tx)
val parsed = Try(ErgoTransactionSerializer.parseBytes(bytes))
parsed.isFailure shouldBe true
parsed.failed.get.getMessage.contains("Negative id") shouldBe true
}

}
8 changes: 4 additions & 4 deletions ergo-wallet/build.sbt
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// this values should be in sync with root (i.e. ../build.sbt)
val scala211 = "2.11.12"
val scala212 = "2.12.20"
val scala213 = "2.13.16"
val scala213 = "2.13.18"

val deps211 = Seq(
"io.circe" %% "circe-core" % "0.10.0",
"io.circe" %% "circe-generic" % "0.10.0",
"io.circe" %% "circe-parser" % "0.10.0")
val deps212 = Seq(
"io.circe" %% "circe-core" % "0.13.0",
"io.circe" %% "circe-generic" % "0.13.0",
"io.circe" %% "circe-parser" % "0.13.0")
"io.circe" %% "circe-core" % "0.14.15",
"io.circe" %% "circe-generic" % "0.14.15",
"io.circe" %% "circe-parser" % "0.14.15")

libraryDependencies ++= Seq(
"org.scodec" %% "scodec-bits" % "1.1.34",
Expand Down
Loading