-
Notifications
You must be signed in to change notification settings - Fork 167
/
ProverNodeSerializer.scala
71 lines (64 loc) · 2.61 KB
/
ProverNodeSerializer.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package scorex.crypto.authds.avltree.batch
import com.google.common.primitives.Ints
import org.ergoplatform.serialization.ErgoSerializer
import scorex.crypto.authds.{ADKey, ADValue, Balance}
import scorex.crypto.authds.avltree.batch.Constants.{DigestType, hashFn}
import scorex.crypto.authds.avltree.batch.serialization.ProxyInternalNode
import scorex.crypto.hash.Digest32
import scorex.db.LDBVersionedStore
import scorex.util.serialization.{Reader, Writer}
/**
* ErgoSerializer based prover nodes serializer (alternative to one provided in scrypto which is doing much more
* allocations)
*
* @param store - store which could be provided to fetch children of a node when a child is requested
*/
class ProverNodeSerializer(store: LDBVersionedStore) extends ErgoSerializer[ProverNodes[DigestType]] {
import VersionedLDBAVLStorage.{InternalNodePrefix,LeafPrefix}
override def serialize(node: ProverNodes[DigestType], w: Writer): Unit = {
node match {
case n: ProxyInternalNode[DigestType] =>
w.put(InternalNodePrefix)
w.put(n.balance)
w.putBytes(n.key)
w.putBytes(n.leftLabel)
w.putBytes(n.rightLabel)
case n: InternalProverNode[DigestType] =>
w.put(InternalNodePrefix)
w.put(n.balance)
w.putBytes(n.key)
w.putBytes(n.left.label)
w.putBytes(n.right.label)
case n: ProverLeaf[DigestType] =>
w.put(LeafPrefix)
w.putBytes(n.key)
w.putBytes(Ints.toByteArray(n.value.length))
w.putBytes(n.value)
w.putBytes(n.nextLeafKey)
}
}
override def parse(r: Reader): ProverNodes[DigestType] = {
val prefix = r.getByte()
prefix match {
case InternalNodePrefix =>
val balance = Balance @@ r.getByte()
val key = ADKey @@ r.getBytes(StateTreeParameters.keySize)
val leftKey = ADKey @@ r.getBytes(StateTreeParameters.labelSize)
val rightKey = ADKey @@ r.getBytes(StateTreeParameters.labelSize)
if (store != null) {
new ProxyInternalProverNode(key, leftKey, rightKey, balance)(store)
} else {
new ProxyInternalNode[DigestType](key, Digest32 @@@ leftKey, Digest32 @@@ rightKey, balance)(hashFn)
}
case LeafPrefix =>
val key = ADKey @@ r.getBytes(StateTreeParameters.keySize)
val (value, nextLeafKey) = {
val valueSize = Ints.fromByteArray(r.getBytes(4))
val value = ADValue @@ r.getBytes(valueSize)
val nextLeafKey = ADKey @@ r.getBytes(StateTreeParameters.keySize)
value -> nextLeafKey
}
new ProverLeaf[DigestType](key, value, nextLeafKey)(hashFn)
}
}
}