use of tech.pegasys.teku.infrastructure.ssz.tree.SszSuperNode in project teku by ConsenSys.
the class AbstractSszListSchema method loadBackingNodes.
@Override
public TreeNode loadBackingNodes(final TreeNodeSource nodeSource, final Bytes32 rootHash, final long rootGIndex) {
if (TreeUtil.ZERO_TREES_BY_ROOT.containsKey(rootHash) || rootHash.equals(Bytes32.ZERO)) {
return getDefaultTree();
}
final CompressedBranchInfo branchData = nodeSource.loadBranchNode(rootHash, rootGIndex);
checkState(branchData.getChildren().length == 2, "List root node must have exactly two children");
checkState(branchData.getDepth() == 1, "List root node must have depth of 1");
final Bytes32 vectorHash = branchData.getChildren()[0];
final Bytes32 lengthHash = branchData.getChildren()[1];
final int length = nodeSource.loadLeafNode(lengthHash, GIndexUtil.gIdxRightGIndex(rootGIndex)).getInt(0, ByteOrder.LITTLE_ENDIAN);
final int superNodeDepth = getSuperNodeDepth();
final ChildLoader childLoader = superNodeDepth == 0 ? (childNodeSource, childHash, childGIndex) -> LoadingUtil.loadCollectionChild(childNodeSource, childHash, childGIndex, length, compatibleVectorSchema.getElementsPerChunk(), compatibleVectorSchema.treeDepth(), compatibleVectorSchema.getElementSchema()) : (childNodeSource, childHash, childGIndex) -> {
final Bytes data;
if (TreeUtil.ZERO_TREES_BY_ROOT.containsKey(childHash)) {
data = Bytes.EMPTY;
} else {
data = nodeSource.loadLeafNode(childHash, childGIndex);
}
return new SszSuperNode(superNodeDepth, elementSszSupernodeTemplate.get(), data);
};
final long vectorRootGIndex = GIndexUtil.gIdxLeftGIndex(rootGIndex);
final long lastUsefulGIndex = getVectorLastUsefulGIndex(vectorRootGIndex, length, superNodeDepth);
final TreeNode vectorNode = LoadingUtil.loadNodesToDepth(nodeSource, vectorHash, vectorRootGIndex, compatibleVectorSchema.treeDepth() - superNodeDepth, compatibleVectorSchema.getDefault().getBackingNode(), lastUsefulGIndex, childLoader);
return BranchNode.create(vectorNode, toLengthNode(length));
}
use of tech.pegasys.teku.infrastructure.ssz.tree.SszSuperNode in project teku by ConsenSys.
the class AbstractSszCollectionSchema method sszDeserializeSupernode.
private DeserializedData sszDeserializeSupernode(SszReader reader, int supernodeDepth) {
SszNodeTemplate template = elementSszSupernodeTemplate.get();
int sszSize = reader.getAvailableBytes();
if (sszSize % template.getSszLength() != 0) {
throw new SszDeserializeException("Ssz length is not multiple of element length");
}
int elementsCount = sszSize / template.getSszLength();
int chunkSize = (1 << supernodeDepth) * template.getSszLength();
int bytesRemain = sszSize;
List<SszSuperNode> sszNodes = new ArrayList<>(bytesRemain / chunkSize + 1);
while (bytesRemain > 0) {
int toRead = min(bytesRemain, chunkSize);
bytesRemain -= toRead;
Bytes bytes = reader.read(toRead);
SszSuperNode node = new SszSuperNode(supernodeDepth, template, bytes);
sszNodes.add(node);
}
TreeNode tree = TreeUtil.createTree(sszNodes, new SszSuperNode(supernodeDepth, template, Bytes.EMPTY), treeDepth() - supernodeDepth);
return new DeserializedData(tree, elementsCount);
}
use of tech.pegasys.teku.infrastructure.ssz.tree.SszSuperNode in project teku by ConsenSys.
the class AbstractSszVectorSchema method createDefaultTree.
@Override
protected TreeNode createDefaultTree() {
if (isListBacking) {
Optional<SszSuperNodeHint> sszSuperNodeHint = getHints().getHint(SszSuperNodeHint.class);
if (sszSuperNodeHint.isPresent()) {
int superNodeDepth = sszSuperNodeHint.get().getDepth();
SszSuperNode defaultSuperSszNode = new SszSuperNode(superNodeDepth, elementSszSupernodeTemplate.get(), Bytes.EMPTY);
int binaryDepth = treeDepth() - superNodeDepth;
return TreeUtil.createTree(emptyList(), defaultSuperSszNode, binaryDepth);
} else {
return TreeUtil.createDefaultTree(maxChunks(), LeafNode.EMPTY_LEAF);
}
} else if (getElementsPerChunk() == 1) {
return TreeUtil.createDefaultTree(maxChunks(), getElementSchema().getDefaultTree());
} else {
// packed vector
int fullZeroNodesCount = getLength() / getElementsPerChunk();
int lastNodeElementCount = getLength() % getElementsPerChunk();
int lastNodeSizeBytes = bitsCeilToBytes(lastNodeElementCount * getSszElementBitSize());
Stream<TreeNode> fullZeroNodes = Stream.<TreeNode>generate(() -> LeafNode.ZERO_LEAVES[32]).limit(fullZeroNodesCount);
Stream<TreeNode> lastZeroNode = lastNodeSizeBytes > 0 ? Stream.of(LeafNode.ZERO_LEAVES[lastNodeSizeBytes]) : Stream.empty();
return TreeUtil.createTree(Stream.concat(fullZeroNodes, lastZeroNode).collect(Collectors.toList()));
}
}
Aggregations