Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P2P networking support for bootstrapping with UTXO set snapshot #1444

Merged
merged 208 commits into from
May 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
208 commits
Select commit Hold shift + click to select a range
a5b7bf0
utxo.md started
kushti Sep 13, 2021
c25a267
Merge branch 'v4.0.15' of github.com:ergoplatform/ergo into utxo-set-…
kushti Sep 27, 2021
1083fb9
snapshotsToKeep setting, UtxoSnapshotExample
kushti Sep 27, 2021
f5b6dd4
Merge branch 'v4.0.16' of github.com:ergoplatform/ergo into utxo-set-…
kushti Nov 2, 2021
9fca93e
leafDataStats
kushti Nov 3, 2021
5b0229d
utxoBootstrap flag
kushti Nov 3, 2021
b1226c6
UTXOSnapshotChunk rework #1
kushti Nov 3, 2021
5673b2c
get tree stats via traversal
kushti Nov 5, 2021
d17b9e3
utxo snapshot entities rework #2
kushti Nov 11, 2021
1b605dd
Merge branch 'scorex-ref-2' of github.com:ergoplatform/ergo into utxo…
kushti Nov 11, 2021
956388d
estimatedTip parameter
kushti Nov 11, 2021
72eba60
save snapshot condition
kushti Nov 11, 2021
dcab0a3
saveSnapshotIfNeeded stub
kushti Nov 11, 2021
0838f27
Merge branch 'v4.0.17' of github.com:ergoplatform/ergo into utxo-set-…
kushti Nov 13, 2021
72c91f9
comparing common subtrees experiment
kushti Nov 13, 2021
e6924aa
starting SnapshotsDb
kushti Nov 13, 2021
e4f569c
estimatedTip fix, postponing wallet scanning
kushti Nov 15, 2021
5ded2ed
Merge branch 'v4.0.17' of github.com:ergoplatform/ergo into utxo-set-…
kushti Nov 17, 2021
d2ab04e
writeSnapshotsInfo / readSnapshotsInfo
kushti Nov 17, 2021
229b55b
writeSnapshot / readManifestBytes / readSubtreeBytes
kushti Nov 18, 2021
506776f
writing snapshots to the disk
kushti Nov 18, 2021
84828c7
Merge branch 'v4.0.17' of github.com:ergoplatform/ergo into utxo-set-…
kushti Nov 22, 2021
85f1a45
Merge branch 'v4.0.17' of github.com:ergoplatform/ergo into utxo-set-…
kushti Nov 25, 2021
4b0aa89
pruneSnapshots
kushti Nov 25, 2021
2d3aa31
calling prune()
kushti Nov 26, 2021
8705e23
Merge branch 'v4.0.17' of github.com:ergoplatform/ergo into utxo-set-…
kushti Nov 29, 2021
cea355d
removing experimental manifests comparison code
kushti Nov 29, 2021
8c47902
removing snapshotsToKeep setting
kushti Nov 29, 2021
90060b9
BlockSection, comment for applyModifier
kushti Nov 29, 2021
6b2a248
optimizing apply code in *Synchronizer actors
kushti Nov 29, 2021
a76d546
utxoNetworkingSupported
kushti Nov 29, 2021
0352912
Implement getSnapshotsInfo message
knizhnik Dec 6, 2021
58d9a1b
Add GetSnapshotsInfoSpec/SnapshotsInfoSpec
knizhnik Dec 7, 2021
2d3f4d9
fromLatestSnapshot
kushti Dec 7, 2021
b76f5af
Merge branch 'v4.0.17' of github.com:ergoplatform/ergo into utxo-set-…
kushti Dec 7, 2021
80ed884
Handle GetSnapshotsInfo message in ErgoNodeViewSycnhronizer
knizhnik Dec 10, 2021
22d9adb
Merge branch 'utxo-snapshot-networking' of github.com:ergoplatform/er…
kushti Dec 14, 2021
7c743dc
fixing messages sizes
kushti Dec 14, 2021
3e875cc
merging with remote
kushti Dec 14, 2021
f9c6ead
ChangedState
kushti Dec 14, 2021
26f4f3c
Fix sending GetSnapshotsInfo message
knizhnik Dec 18, 2021
6c63fa7
fixing GetSnapshotInfo
kushti Dec 21, 2021
84bd7a3
Merge pull request #1521 from ergoplatform/i1517
kushti Dec 22, 2021
78dc2de
merging w. master
kushti Dec 29, 2021
2d21df5
merging with parent branch
kushti Dec 29, 2021
58ec522
merging w. remote
kushti Dec 30, 2021
a77205f
fixing getsnapshot processing
kushti Dec 30, 2021
f37c72e
Add GetManifest/GetSnapshotChunk messages
knizhnik Jan 11, 2022
427aec2
Fix matching messages in msgHandlers
knizhnik Jan 12, 2022
a405038
slicedTree, simplifying tests
kushti Jan 13, 2022
71e20da
increased manifest and chunk message size limits
kushti Jan 13, 2022
31a0b3d
Merge pull request #1571 from ergoplatform/i1552
kushti Jan 13, 2022
333e56e
merging w. 4.0.32
kushti Jun 11, 2022
1c69cde
merging w. 4.0.35 candidate
kushti Jul 5, 2022
52794bc
merging with ENVS refactoring
kushti Jul 5, 2022
31eb791
Merge branch 'v4.0.37' of github.com:ergoplatform/ergo into utxo-set-…
kushti Aug 1, 2022
5082d0d
merging w. 4.0.37
kushti Aug 2, 2022
c6a6de1
Merge branch 'v4.0.37' of github.com:ergoplatform/ergo into utxo-set-…
kushti Aug 3, 2022
3f73ad7
UtxoSetNetworkingFilter
kushti Aug 3, 2022
cf06782
merging w. remote
kushti Aug 3, 2022
007ad88
fixing imports
kushti Aug 3, 2022
12c7fde
Merge branch 'v4.0.39' of github.com:ergoplatform/ergo into utxo-set-…
kushti Aug 7, 2022
d6322ca
merging w. 4.0.37
kushti Aug 7, 2022
c60a69b
MapPimp moved to score.core.utils
kushti Aug 8, 2022
f33b218
cosmetic improvements in nextModifiersToDownload
kushti Aug 8, 2022
a7cce4d
synthetic snapshotsinfo id, requesting snapshotsinfo from nextModifie…
kushti Aug 8, 2022
537eebc
ElementPartitioner.distribute signature changed
kushti Aug 10, 2022
5ded307
merging w. 5.0.4
kushti Nov 23, 2022
de846ec
Merge branch 'v5.0.4' of github.com:ergoplatform/ergo into utxo-set-b…
kushti Nov 24, 2022
d961daa
new sections in EIP draft
kushti Nov 24, 2022
b9284c2
trying to read snapshot on start if state is empty
kushti Nov 24, 2022
6aaeb27
log.info instead of println
kushti Nov 26, 2022
26047e9
Merge branch 'v5.0.4' of github.com:ergoplatform/ergo into utxo-set-b…
kushti Nov 30, 2022
b2a52d8
sectionIdsWithNoProof
kushti Nov 30, 2022
035b43a
trait FullBlockPruningProcessor
kushti Nov 30, 2022
e3e2c59
estimatedTip parameter removed from nextModifiersToDownload
kushti Nov 30, 2022
6369ecb
merging w. utxo-set-bootstrapping
kushti Nov 30, 2022
a682d75
Merge pull request #1514 from ergoplatform/utxo-snapshot-networking
kushti Nov 30, 2022
e613f93
requestSnapshotInfo
kushti Dec 2, 2022
346c8ab
requestsManifest, processSnapshotsInfo, checkUtxoSetManifests
kushti Dec 2, 2022
e0595b7
finishing checkUtxoSetManifests
kushti Dec 2, 2022
593cfe4
requestUtxoSetChunk , processManifest
kushti Dec 3, 2022
80f87e7
processUtxoSnapshotChunk
kushti Dec 4, 2022
60d66e2
InitStateFromSnapshot
kushti Dec 5, 2022
b13961c
Merge branch 'v5.0.5' of github.com:ergoplatform/ergo into utxo-set-b…
kushti Dec 8, 2022
20b5437
more log output
kushti Dec 8, 2022
9781ef2
fixin init issues
kushti Dec 8, 2022
61331b5
manifestChosen removed, comment added
kushti Dec 8, 2022
db5dd1a
UtxoSetSnapshotPersistence, more comments, testing section in doc
kushti Dec 9, 2022
94ff33e
utxo set snapshot filter test
kushti Dec 10, 2022
5f059df
known peers in sync tracker
kushti Dec 10, 2022
b387aa6
log in sendSnapshotsInfo
kushti Dec 10, 2022
438bd7d
messageHandlers fixed in ErgoApp, Application trait removed
kushti Dec 10, 2022
00fd66f
fixing basicSpecs, increased max size for SnapshotsInfo
kushti Dec 10, 2022
b6962c0
checkUtxoSetManifests
kushti Dec 10, 2022
637c5c8
getSnapshotInfo, getManifest, getUtxoSnapshotChunk moved to UtxoSetSn…
kushti Dec 12, 2022
edbb1c7
updating snapshots info on pruneSnapshots
kushti Dec 12, 2022
42bf44b
downloading latest snapshot
kushti Dec 12, 2022
605c77d
debug log on sending out chunks
kushti Dec 12, 2022
e643271
requestMoreChunksIfNeeded
kushti Dec 13, 2022
e2d0ba0
moving isGenesis to reader
kushti Dec 13, 2022
6ce1111
utxoSnapshotApplied
kushti Dec 13, 2022
381e281
UtxoSetSnapshotDownloadPlan, writeDownloadPlanToTheDb, readDownloadPl…
kushti Dec 15, 2022
c22a4a4
registerManifestToDownload, getUtxoSetSnapshotDownloadPlan
kushti Dec 15, 2022
566780c
persistence for utxo set snapshot chunks
kushti Dec 19, 2022
9b2d5f6
InitStateFromSnapshot not passing data
kushti Dec 20, 2022
85864ef
createPersistentProver
kushti Dec 22, 2022
484c037
polishing createPersistentProver, initial version of InitStateFromSna…
kushti Dec 22, 2022
f96dc1f
writing metadata to state db
kushti Dec 22, 2022
9f31fab
UtxoSetSnapshotProcessorSpecification, downloadedChunksIterator
kushti Dec 23, 2022
5ea4969
downloading from multiple peers
kushti Dec 23, 2022
37537d4
no persistence for downloading plan, logging improvs
kushti Dec 24, 2022
7fd67c1
re-requesting non-delivered utxo set chunks via delivery tracker, do …
kushti Dec 26, 2022
48c0a56
first real test in UtxoSetSnapshotProcessorSpecification
kushti Dec 26, 2022
51ece26
downloadedChunksIterator & createPersistentProver covered in test
kushti Dec 26, 2022
6bb08d8
bigger state size in test
kushti Dec 27, 2022
dc69ee2
fixing proxy nodes serialization
kushti Dec 28, 2022
bd9f697
redownloading chunk fixed
kushti Dec 30, 2022
5dfe30d
Merge branch 'v5.0.5' of github.com:ergoplatform/ergo into utxo-set-b…
kushti Dec 30, 2022
23df49c
warning on double state application attempt
kushti Dec 30, 2022
dbf8d49
downloadPlanOpt, tweaking downloading params
kushti Dec 31, 2022
022855d
MinSnapshots = 2, more debug logging
kushti Jan 1, 2023
d30be43
logging peers chunks will be downloaded from
kushti Jan 1, 2023
5c70a2c
clearing availableManifests, scaladoc for it
kushti Jan 1, 2023
9f10438
fixing duplicates in availableManifests
kushti Jan 1, 2023
f22380c
fixing duplicates in availableManifests
kushti Jan 1, 2023
4dca828
fixing sectionIdsWithNoProof def
kushti Jan 2, 2023
a5b7cf9
ProxyInternalProverNode parameter names fix, ScalaDoc
kushti Jan 2, 2023
41f7aa2
ProxyInternalProverNode scaladoc
kushti Jan 2, 2023
695efec
nodeKey => nodeLabel, more scaladoc in VersionedLDBAVLStorage
kushti Jan 3, 2023
572a80f
Merge branch 'v5.0.5' of github.com:ergoplatform/ergo into utxo-set-b…
kushti Jan 7, 2023
cfc37fb
fromSnapshot removed
kushti Jan 8, 2023
ebdb513
unused code for state recovering removed
kushti Jan 8, 2023
6b130da
UtxoSnapshotChunk removed
kushti Jan 9, 2023
13068e3
UTXOSnapshotManifest removed
kushti Jan 9, 2023
77b774c
PoPoWProof removal, ModifierTypeId trait
kushti Jan 10, 2023
e840c1b
Merge branch 'master' of github.com:ergoplatform/ergo into utxo-set-b…
kushti Jan 11, 2023
e7c4983
Merge branch 'master' of github.com:ergoplatform/ergo into utxo-set-b…
kushti Jan 12, 2023
f153c66
ScalaDocs in VersionedLDBAVLStorage
kushti Jan 12, 2023
17142c5
Merge branch 'master' of github.com:ergoplatform/ergo into utxo-set-b…
kushti Jan 13, 2023
98e6c97
extracting recreate to VersionedLDBAVLStorage object
kushti Jan 14, 2023
4289417
Merge branch 'master' of github.com:ergoplatform/ergo into utxo-set-b…
kushti Jan 16, 2023
0ba48cc
penalizing peer for sending wrong bytes
kushti Jan 16, 2023
7ef0fbe
merging w. master
kushti Jan 16, 2023
df13aff
minor styling improvements
kushti Jan 17, 2023
bdac932
NetworkObjectTypeId -> ModifierTypeId, ScalaDoc
kushti Jan 24, 2023
4ba17f2
ScalaDoc for HF in VersionedLDBAVLStorage
kushti Jan 26, 2023
b28f00a
merging w. 5.0.7
kushti Feb 1, 2023
24d9728
StateTreeParameters replacing instantiations
kushti Feb 2, 2023
96bd7c2
importing some changes from nipopow-bootstrapping
kushti Feb 2, 2023
09bdb67
SnapshotsInfoSpecification
kushti Feb 3, 2023
8612322
writeSnapshot temporal rework, unused methods removed from SnapshotsDb
kushti Feb 3, 2023
f988d35
merging w. 5.0.7
kushti Feb 6, 2023
1707790
merging with master
kushti Feb 27, 2023
2da650a
more elegant solution for topNodeKey / topNodeHeight
kushti Feb 27, 2023
3059103
storingUtxoSnapshots setting
kushti Mar 1, 2023
7803bec
storing from snapshot
kushti Mar 13, 2023
33fe159
fixing test
kushti Mar 14, 2023
3aa3281
dump in Future, code cleaning
kushti Mar 20, 2023
2c83233
moving Future call to saveSnapshotIfNeeded
kushti Mar 24, 2023
5c1f825
ErgoSerializer, scaladoc
kushti Mar 24, 2023
3bfbca7
removing writeDownloadPlanToTheDb
kushti Mar 24, 2023
31b9641
merging w. master
kushti Apr 17, 2023
e12bc76
merging most of biggest changes from preparation branch
kushti Apr 17, 2023
d4b0603
importing DiffSer and comments from preparation branch
kushti Apr 18, 2023
31296c6
Merge branch 'master' of github.com:ergoplatform/ergo into utxo-set-b…
kushti Apr 18, 2023
a5b6531
SnapshotsInfoSerializer
kushti Apr 19, 2023
f067833
pruneSnapshots considers num of snapshots to store setting
kushti Apr 19, 2023
a1b44f7
test for pruning
kushti Apr 19, 2023
0d86318
scaladoc in SnapshotsDb
kushti Apr 20, 2023
2f539cc
constants in state made protected, removing unused vals in ErgoStateR…
kushti Apr 20, 2023
c1c0922
UtxoSetSnapshotPersistence scaladoc
kushti Apr 20, 2023
583ecc0
expectedRootHash
kushti Apr 21, 2023
ccfa678
pulling changes from preparation
kushti Apr 24, 2023
7778623
merging w 5.0.11
kushti Apr 25, 2023
2c8a8bb
remove manifests for height if contradictions are found
kushti Apr 25, 2023
7e12ac7
UtxoSettings
kushti Apr 26, 2023
6db2c62
fixing MinSnapshots in checkUtxoSetManifests
kushti Apr 26, 2023
111b881
BlockSectionTypeId / AuxiliaryTypeId
kushti Apr 26, 2023
f919805
BlockSectionThreshold / isBlockSection
kushti Apr 26, 2023
3aa87db
ManifestTypeId, checking if utxo set snapshot chunk was requested
kushti Apr 28, 2023
724958a
eliminating BatchAVLProverSerializer usages, spam manifest check
kushti May 1, 2023
a545164
polishing requestMoreChunksIfNeeded
kushti May 1, 2023
84b79e9
merging w. 5.0.12
kushti May 1, 2023
957429b
matching download plan in processUtxoSnapshotChunk
kushti May 1, 2023
b59e04f
bestHeaderIdAtHeight.get fixed
kushti May 1, 2023
95d2168
_utxoSnapshotApplied made private
kushti May 2, 2023
57f1010
removing unused code #1
kushti May 2, 2023
ed8b416
removing unused code #2
kushti May 2, 2023
b73ef27
fixes in NetworkObjectTypeId hierarchy, fix in nodeConfigurationReader
kushti May 3, 2023
9be0153
close #1991: LDBKVStore.insert for pairs eliminated
kushti May 3, 2023
fd35b3e
5.0.12 todo removed
kushti May 4, 2023
74ef9d6
handling empty peers in requestDownload, scaladoc fixes
kushti May 4, 2023
0482fc7
handling empty peers case in distribute, more scaladoc
kushti May 4, 2023
fad8784
peersToDownload added to download plan
kushti May 4, 2023
178bd2d
code cleaning 1
kushti May 5, 2023
54f601c
_utxoSnapshotApplied removed, startingTime removed from UtxoSetSnapsh…
kushti May 5, 2023
4cc7d55
UtxoSetSnapshotDownloadPlan scaladoc
kushti May 8, 2023
133f82d
externalizing UtxoSetSnapshotDownloadPlan
kushti May 8, 2023
4fcb85b
UtxoSetSnapshotProcessor cleanup and scaladocs
kushti May 9, 2023
f635b37
more code polishing
kushti May 9, 2023
eb1b033
Merge branch 'utxo-set-bootstrapping' of github.com:ergoplatform/ergo…
kushti May 9, 2023
946e70d
Merge pull request #1992 from ergoplatform/i1991
kushti May 10, 2023
1feac92
emptyArrayOfByteArray
kushti May 11, 2023
f4b2654
manifest verification, comments addressed
kushti May 12, 2023
a272ffc
utxo-set-bootstrapping: typos
aslesarenko May 12, 2023
f3d2a5d
merging w. 5.0.12
kushti May 12, 2023
e63ea9b
Merge branch 'utxo-set-bootstrapping' of github.com:ergoplatform/ergo…
kushti May 12, 2023
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
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package scorex.core.serialization

import com.google.common.primitives.Ints
import scorex.crypto.authds.avltree.batch.Constants.DigestType
import scorex.crypto.authds.avltree.batch.serialization.{BatchAVLProverManifest, ProxyInternalNode}
import scorex.crypto.authds.avltree.batch.{InternalProverNode, ProverLeaf, ProverNodes, VersionedLDBAVLStorage}
Expand All @@ -13,8 +12,8 @@ class ManifestSerializer(manifestDepth: Byte) extends ErgoSerializer[BatchAVLPro
private val nodeSerializer = VersionedLDBAVLStorage.noStoreSerializer

override def serialize(manifest: BatchAVLProverManifest[DigestType], w: Writer): Unit = {
val height = manifest.rootHeight
w.putBytes(Ints.toByteArray(height))
val rootNodeHeight = manifest.rootHeight.toByte
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't it be toByteExact?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, by construction AVL+ tree has height <= 127 , then manifest has the same limitation also. Need to fix manifest in scrypto about that

Copy link
Member

Choose a reason for hiding this comment

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

Yes, but it makes more assumption about input data. If however there is a mistake in the data, the silent overflow will lead to hard to localize bugs. Why not to do checks here? It will not impact performance.

Copy link
Member Author

Choose a reason for hiding this comment

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

There MUST BE NOT mistakes here, if prover is having root height > 127 it can not work with the tree simply, forming bad manifest is very secondary issue then. Even more, height is much less than 127 always, there is a descriptive comment in scrypto about that.

Copy link
Member

Choose a reason for hiding this comment

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

ok, I just curious why you think not checking overflow is better than checking?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because it could be more confusing actually for a reader to find a check for a thing which MUST NOT happen by construction. Conversion to int in some manifest / db classes is already confusing.

w.put(rootNodeHeight)
w.put(manifestDepth)

def loop(node: ProverNodes[DigestType], level: Int): Unit = {
Expand All @@ -32,10 +31,11 @@ class ManifestSerializer(manifestDepth: Byte) extends ErgoSerializer[BatchAVLPro
}

override def parse(r: Reader): BatchAVLProverManifest[DigestType] = {
val rootHeight = Ints.fromByteArray(r.getBytes(4))
val rootHeight = r.getByte()
val manifestDepth = r.getByte()

require(manifestDepth == this.manifestDepth, "Wrong manifest depth")
require(manifestDepth == this.manifestDepth,
s"Wrong manifest depth, found: $manifestDepth, expected: ${this.manifestDepth}")

def loop(level: Int): ProverNodes[DigestType] = {
val node = nodeSerializer.parse(r)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package scorex.crypto.authds.avltree.batch

import com.google.common.primitives.Ints
import scorex.core.serialization.ManifestSerializer
import scorex.crypto.authds.avltree.batch.Constants.{DigestType, HashFnType, hashFn}
import scorex.crypto.authds.avltree.batch.VersionedLDBAVLStorage.{topNodeHashKey, topNodeHeightKey}
import scorex.crypto.authds.avltree.batch.serialization.{BatchAVLProverManifest, BatchAVLProverSubtree, ProxyInternalNode}
Expand Down Expand Up @@ -98,7 +97,7 @@ class VersionedLDBAVLStorage(store: LDBVersionedStore)
* @param expectedRootHash - expected UTXO set authenticating tree root hash
* @return - hash of root node of tree, or failure if an error (e.g. in database) happened
*/
def dumpSnapshot(dumpStorage: LDBKVStore, manifestDepth: Int, expectedRootHash: Array[Byte]): Try[Array[Byte]] = {
def dumpSnapshot(dumpStorage: LDBKVStore, manifestDepth: Byte, expectedRootHash: Array[Byte]): Try[Array[Byte]] = {
store.processSnapshot { dbReader =>

def subtreeLoop(label: DigestType, builder: mutable.ArrayBuilder[Byte]): Unit = {
Expand Down Expand Up @@ -137,14 +136,14 @@ class VersionedLDBAVLStorage(store: LDBVersionedStore)
}

val rootNodeLabel = dbReader.get(topNodeHashKey)
val rootNodeHeight = Ints.fromByteArray(dbReader.get(topNodeHeightKey))
val rootNodeHeight = Ints.fromByteArray(dbReader.get(topNodeHeightKey)).toByte
aslesarenko marked this conversation as resolved.
Show resolved Hide resolved

require(rootNodeLabel.sameElements(expectedRootHash), "Root node hash changed")

val manifestBuilder = mutable.ArrayBuilder.make[Byte]()
manifestBuilder.sizeHint(200000)
manifestBuilder ++= Ints.toByteArray(rootNodeHeight)
manifestBuilder += ManifestSerializer.MainnetManifestDepth
manifestBuilder += rootNodeHeight
manifestBuilder += manifestDepth

manifestLoop(rootNodeLabel, level = 1, manifestBuilder)
val manifestBytes = manifestBuilder.result()
Expand Down Expand Up @@ -232,7 +231,7 @@ object VersionedLDBAVLStorage {
* Calculate tree digest, given root node label(hash) and root node height, by appending height to the hash
*/
def digest[D <: hash.Digest](rootNodeLabel: D, rootNodeHeight: Int): ADDigest = {
assert(rootNodeHeight >= 0 && rootNodeHeight < 256)
assert(rootNodeHeight >= 0 && rootNodeHeight <= 127)
// rootNodeHeight should never be more than 255, so the toByte conversion is safe (though it may cause an incorrect
// sign on the signed byte if rootHeight>127, but we handle that case correctly on decoding the byte back to int in the
// verifier, by adding 256 if it's negative).
Expand All @@ -241,4 +240,11 @@ object VersionedLDBAVLStorage {
ADDigest @@ (rootNodeLabel :+ rootNodeHeight.toByte)
}

/**
* splits 33-byte digest into 32-bytes hash and 1-byte tree height
*/
def splitDigest(digest: ADDigest): (Array[Byte], Byte) = {
digest.dropRight(1) -> digest.takeRight(1).head
}

}
12 changes: 7 additions & 5 deletions avldb/src/main/scala/scorex/db/LDBKVStore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import spire.syntax.all.cfor
* Both keys and values are var-sized byte arrays.
*/
class LDBKVStore(protected val db: DB) extends KVStoreReader with ScorexLogging {
private val emptyArrayOfByteArray = Array.empty[Array[Byte]]

/**
* Update this database atomically with a batch of insertion and removal operations
Expand Down Expand Up @@ -55,15 +56,16 @@ class LDBKVStore(protected val db: DB) extends KVStoreReader with ScorexLogging
/**
* `update` variant where we only insert values into this database
*/
def insert(keys: Array[K], values: Array[V]): Try[Unit] = update(keys, values, Array.empty)

def insert(values: Array[(K, V)]): Try[Unit] = update(values.map(_._1), values.map(_._2), Array.empty)

def insert(keys: Array[K], values: Array[V]): Try[Unit] = {
update(keys, values, emptyArrayOfByteArray)
}

/**
* `update` variant where we only remove values from this database
*/
def remove(keys: Array[K]): Try[Unit] = update(Array.empty, Array.empty, keys)
def remove(keys: Array[K]): Try[Unit] = {
update(emptyArrayOfByteArray, emptyArrayOfByteArray, keys)
}

/**
* Get last key within some range (inclusive) by used comparator.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ object LDBStoreBench
val txsWithDbGen: Gen[(Seq[BlockTransactions], LDBKVStore)] = txsGen.map { bts =>
val toInsert = bts.map(bt => idToBytes(bt.headerId) -> bt.bytes).toArray
val db = storeLDB()
toInsert.grouped(5).foreach(db.insert(_).get)
toInsert.grouped(5).foreach(kv => db.insert(kv.map(_._1), kv.map(_._2)).get)
bts -> storeLDB
}

Expand All @@ -55,7 +55,7 @@ object LDBStoreBench
private def benchWriteLDB(bts: Seq[BlockTransactions]): Unit = {
val toInsert = bts.map(bt => idToBytes(bt.headerId) -> bt.bytes).toArray
val db = storeLDB()
toInsert.grouped(5).foreach(db.insert(_).get)
toInsert.grouped(5).foreach(kv => db.insert(kv.map(_._1), kv.map(_._2)).get)
}

private def benchReadLDB(bts: Seq[BlockTransactions], db: LDBKVStore): Unit = {
Expand Down
6 changes: 0 additions & 6 deletions papers/emission.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,6 @@ second one is to pay mining fee supposedly (its value can be 0.01 ERG at most)

val correctNftId = EQ(firstTokenId, ByteArrayConstant(reemissionNftId))

// output of the reemission contract
val reemissionOut = ByIndex(Outputs, IntConstant(0))

// output to pay miner
val minerOut = ByIndex(Outputs, IntConstant(1))

// miner's output must have script which is time-locking reward for miner's pubkey
// box height must be the same as block height
val correctMinerOutput = AND(
Expand Down
33 changes: 33 additions & 0 deletions src/main/resources/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ components:
bytes:
$ref: '#/components/schemas/HexString'

SnapshotsInfo:
type: object
required:
- availableManifests
properties:
availableManifests:
description: Map of available manifests height -> manifestId
type: array
items:
type: object

ErgoTransactionOutput:
type: object
required:
Expand Down Expand Up @@ -5077,6 +5088,28 @@ paths:
schema:
$ref: '#/components/schemas/ApiError'

/utxo/getSnapshotsInfo:
get:
summary: Get information about locally stored UTXO snapshots
operationId: getSnapshotsInfo
tags:
- utxo
responses:
'200':
description: A list of saved snapshots
content:
application/json:
schema:
$ref: '#/components/schemas/SnapshotsInfo'
default:
description: Error
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'



/utxo/genesis:
get:
summary: Get genesis boxes (boxes existed before the very first block)
Expand Down
16 changes: 13 additions & 3 deletions src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,18 @@ ergo {
# otherwise, it could be hard to find proofs around the peers
blocksToKeep = -1

# Download and apply UTXO set snapshot and full-blocks after that
utxoBootstrap = false
utxo {
# Download and apply UTXO set snapshot and full-blocks after that
utxoBootstrap = false

# how many utxo set snapshots to store, 0 means that they are not stored at all
storingUtxoSnapshots = 0

# how many utxo set snapshots for a height with same id we need to find in p2p network
# in order to start downloading it
p2pUtxoSnapshots = 2
}


# Download PoPoW proof on node bootstrap
PoPoWBootstrap = false
Expand Down Expand Up @@ -106,7 +116,7 @@ ergo {
# }
#
# Before the height given (including it) validation of scripts is missed.
# This improving perfomance and memory usage during initial bootstrapping.
# This improving performance and memory usage during initial bootstrapping.
# The node still applying transactions to UTXO set and so checks UTXO set digests for each block.
# Block at checkpoint height is to be checked against expected one.
checkpoint = null
Expand Down
38 changes: 26 additions & 12 deletions src/main/scala/org/ergoplatform/ErgoApp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,28 +59,35 @@ class ErgoApp(args: Args) extends ScorexLogging {
else None
upnpGateway.foreach(_.addPort(scorexSettings.network.bindAddress.getPort))

//an address to send to peers
private val externalSocketAddress: Option[InetSocketAddress] =
scorexSettings.network.declaredAddress orElse {
upnpGateway.map(u =>
new InetSocketAddress(u.externalAddress, scorexSettings.network.bindAddress.getPort)
)
// own address to send to peers
private val externalSocketAddress: Option[InetSocketAddress] = {
scorexSettings.network.declaredAddress orElse {
upnpGateway.map(u =>
new InetSocketAddress(u.externalAddress, scorexSettings.network.bindAddress.getPort)
)
}
}

private val basicSpecs = {
// descriptors of p2p networking protocol messages
private val p2pMessageSpecifications = {
Seq(
GetPeersSpec,
new PeersSpec(scorexSettings.network.maxPeerSpecObjects),
ErgoSyncInfoMessageSpec,
InvSpec,
RequestModifierSpec,
ModifiersSpec
ModifiersSpec,
GetSnapshotsInfoSpec,
SnapshotsInfoSpec,
GetManifestSpec,
ManifestSpec,
GetUtxoSnapshotChunkSpec,
UtxoSnapshotChunkSpec
)
}

private val additionalMessageSpecs: Seq[MessageSpec[_]] = Seq(ErgoSyncInfoMessageSpec)

private val scorexContext = ScorexContext(
messageSpecs = basicSpecs ++ additionalMessageSpecs,
messageSpecs = p2pMessageSpecifications,
upnpGateway = upnpGateway,
externalNodeAddress = externalSocketAddress
)
Expand Down Expand Up @@ -129,7 +136,14 @@ class ErgoApp(args: Args) extends ScorexLogging {
InvSpec.messageCode -> ergoNodeViewSynchronizerRef,
RequestModifierSpec.messageCode -> ergoNodeViewSynchronizerRef,
ModifiersSpec.messageCode -> ergoNodeViewSynchronizerRef,
ErgoSyncInfoMessageSpec.messageCode -> ergoNodeViewSynchronizerRef
ErgoSyncInfoMessageSpec.messageCode -> ergoNodeViewSynchronizerRef,
// utxo set snapshot exchange related messages
GetSnapshotsInfoSpec.messageCode -> ergoNodeViewSynchronizerRef,
SnapshotsInfoSpec.messageCode -> ergoNodeViewSynchronizerRef,
GetManifestSpec.messageCode -> ergoNodeViewSynchronizerRef,
ManifestSpec.messageCode -> ergoNodeViewSynchronizerRef,
GetUtxoSnapshotChunkSpec.messageCode-> ergoNodeViewSynchronizerRef,
UtxoSnapshotChunkSpec.messageCode -> ergoNodeViewSynchronizerRef
)
// Launching PeerSynchronizer actor which is then registering itself at network controller
if (ergoSettings.scorexSettings.network.peerDiscovery) {
Expand Down
16 changes: 16 additions & 0 deletions src/main/scala/org/ergoplatform/http/api/ApiCodecs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import io.circe.syntax._
import org.ergoplatform.http.api.requests.{CryptoResult, ExecuteRequest, HintExtractionRequest}
import org.ergoplatform.nodeView.history.extra.ExtraIndexer.getAddress
import org.ergoplatform.nodeView.history.extra.{BalanceInfo, IndexedErgoBox, IndexedErgoTransaction, IndexedToken}
import org.ergoplatform.nodeView.state.SnapshotsInfo
import org.ergoplatform.nodeView.state.UtxoState.ManifestId
import org.ergoplatform.wallet.interface4j.SecretString
import scorex.crypto.authds.{LeafData, Side}
import scorex.crypto.authds.merkle.MerkleProof
Expand Down Expand Up @@ -405,6 +407,20 @@ trait ApiCodecs extends JsonCodecs {
} yield TransactionHintsBag(secretHints.mapValues(HintsBag.apply), publicHints.mapValues(HintsBag.apply))
}

implicit val SnapshotInfoEncoder: Encoder[SnapshotsInfo] = { si =>
Json.obj(
"availableManifests" -> si.availableManifests.map { case (height, manifest) =>
height -> manifest
}.asJson
)
}

implicit val SnapshotInfoDecoder: Decoder[SnapshotsInfo] = { cursor =>
for {
availableManifests <- Decoder.decodeMap[Int, ManifestId].tryDecode(cursor.downField("availableManifests"))
} yield new SnapshotsInfo(availableManifests)
}

implicit val transactionSigningRequestEncoder: Encoder[TransactionSigningRequest] = { tsr =>
Json.obj(
"tx" -> tsr.unsignedTx.asJson,
Expand Down
16 changes: 14 additions & 2 deletions src/main/scala/org/ergoplatform/http/api/UtxoApiRoute.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import akka.pattern.ask
import org.ergoplatform.ErgoBox
import org.ergoplatform.nodeView.ErgoReadersHolder.{GetReaders, Readers}
import org.ergoplatform.nodeView.mempool.ErgoMemPoolReader
import org.ergoplatform.nodeView.state.{ErgoStateReader, UtxoStateReader}
import org.ergoplatform.nodeView.state.{ErgoStateReader, UtxoSetSnapshotPersistence, UtxoStateReader}
import org.ergoplatform.wallet.boxes.ErgoBoxSerializer
import scorex.core.api.http.ApiResponse
import scorex.core.settings.RESTApiSettings
Expand All @@ -24,7 +24,7 @@ case class UtxoApiRoute(readersHolder: ActorRef, override val settings: RESTApiS
(readersHolder ? GetReaders).mapTo[Readers].map(rs => (rs.s, rs.m))

override val route: Route = pathPrefix("utxo") {
byId ~ serializedById ~ genesis ~ withPoolById ~ withPoolSerializedById ~ getBoxesBinaryProof
byId ~ serializedById ~ genesis ~ withPoolById ~ withPoolSerializedById ~ getBoxesBinaryProof ~ getSnapshotsInfo
}

def withPoolById: Route = (get & path("withPool" / "byId" / Segment)) { id =>
Expand Down Expand Up @@ -82,4 +82,16 @@ case class UtxoApiRoute(readersHolder: ActorRef, override val settings: RESTApiS
case _ => None
})
}

/**
* Handler for /utxo/getSnapshotsInfo API call which is providing list of
* UTXO set snapshots stored locally
*/
def getSnapshotsInfo: Route = (get & path("getSnapshotsInfo")) {
ApiResponse(getState.map {
case usr: UtxoSetSnapshotPersistence =>
Some(usr.getSnapshotInfo())
case _ => None
})
}
}
Loading