Search in sources :

Example 1 with SszReader

use of tech.pegasys.teku.infrastructure.ssz.sos.SszReader in project teku by ConsenSys.

the class AbstractSszCollectionSchema method sszDeserializeVariable.

private DeserializedData sszDeserializeVariable(SszReader reader) {
    final int endOffset = reader.getAvailableBytes();
    final List<TreeNode> childNodes = new ArrayList<>();
    if (endOffset > 0) {
        int firstElementOffset = SszType.sszBytesToLength(reader.read(SSZ_LENGTH_SIZE));
        checkSsz(firstElementOffset % SSZ_LENGTH_SIZE == 0, "Invalid first element offset");
        int elementsCount = firstElementOffset / SSZ_LENGTH_SIZE;
        checkSsz(elementsCount <= getMaxLength(), "SSZ sequence length exceeds max type length");
        List<Integer> elementOffsets = new ArrayList<>(elementsCount + 1);
        elementOffsets.add(firstElementOffset);
        for (int i = 1; i < elementsCount; i++) {
            int offset = SszType.sszBytesToLength(reader.read(SSZ_LENGTH_SIZE));
            elementOffsets.add(offset);
        }
        elementOffsets.add(endOffset);
        List<Integer> elementSizes = IntStream.range(0, elementOffsets.size() - 1).map(i -> elementOffsets.get(i + 1) - elementOffsets.get(i)).boxed().collect(Collectors.toList());
        if (elementSizes.stream().anyMatch(s -> s < 0)) {
            throw new SszDeserializeException("Invalid SSZ: wrong child offsets");
        }
        for (int elementSize : elementSizes) {
            try (SszReader sszReader = reader.slice(elementSize)) {
                childNodes.add(getElementSchema().sszDeserializeTree(sszReader));
            }
        }
    }
    return new DeserializedData(TreeUtil.createTree(childNodes, treeDepth()), childNodes.size());
}
Also used : SszDeserializeException(tech.pegasys.teku.infrastructure.ssz.sos.SszDeserializeException) SszReader(tech.pegasys.teku.infrastructure.ssz.sos.SszReader) TreeNode(tech.pegasys.teku.infrastructure.ssz.tree.TreeNode) ArrayList(java.util.ArrayList) SszSuperNodeHint(tech.pegasys.teku.infrastructure.ssz.schema.SszSchemaHints.SszSuperNodeHint)

Example 2 with SszReader

use of tech.pegasys.teku.infrastructure.ssz.sos.SszReader in project teku by ConsenSys.

the class AbstractSszContainerSchema method sszDeserializeTree.

@Override
public TreeNode sszDeserializeTree(SszReader reader) {
    int endOffset = reader.getAvailableBytes();
    int childCount = getFieldsCount();
    Queue<TreeNode> fixedChildrenSubtrees = new ArrayDeque<>(childCount);
    List<Integer> variableChildrenOffsets = new ArrayList<>(childCount);
    for (int i = 0; i < childCount; i++) {
        SszSchema<?> childType = getChildSchema(i);
        if (childType.isFixedSize()) {
            try (SszReader sszReader = reader.slice(childType.getSszFixedPartSize())) {
                TreeNode childNode = childType.sszDeserializeTree(sszReader);
                fixedChildrenSubtrees.add(childNode);
            }
        } else {
            int childOffset = SszType.sszBytesToLength(reader.read(SSZ_LENGTH_SIZE));
            variableChildrenOffsets.add(childOffset);
        }
    }
    if (variableChildrenOffsets.isEmpty()) {
        if (reader.getAvailableBytes() > 0) {
            throw new SszDeserializeException("Invalid SSZ: unread bytes for fixed size container");
        }
    } else {
        if (variableChildrenOffsets.get(0) != endOffset - reader.getAvailableBytes()) {
            throw new SszDeserializeException("First variable element offset doesn't match the end of fixed part");
        }
    }
    variableChildrenOffsets.add(endOffset);
    ArrayDeque<Integer> variableChildrenSizes = new ArrayDeque<>(variableChildrenOffsets.size() - 1);
    for (int i = 0; i < variableChildrenOffsets.size() - 1; i++) {
        variableChildrenSizes.add(variableChildrenOffsets.get(i + 1) - variableChildrenOffsets.get(i));
    }
    if (variableChildrenSizes.stream().anyMatch(s -> s < 0)) {
        throw new SszDeserializeException("Invalid SSZ: wrong child offsets");
    }
    List<TreeNode> childrenSubtrees = new ArrayList<>(childCount);
    for (int i = 0; i < childCount; i++) {
        SszSchema<?> childType = getChildSchema(i);
        if (childType.isFixedSize()) {
            childrenSubtrees.add(fixedChildrenSubtrees.remove());
        } else {
            try (SszReader sszReader = reader.slice(variableChildrenSizes.remove())) {
                TreeNode childNode = childType.sszDeserializeTree(sszReader);
                childrenSubtrees.add(childNode);
            }
        }
    }
    return TreeUtil.createTree(childrenSubtrees);
}
Also used : SszDeserializeException(tech.pegasys.teku.infrastructure.ssz.sos.SszDeserializeException) SszReader(tech.pegasys.teku.infrastructure.ssz.sos.SszReader) TreeNode(tech.pegasys.teku.infrastructure.ssz.tree.TreeNode) ArrayList(java.util.ArrayList) ArrayDeque(java.util.ArrayDeque)

Example 3 with SszReader

use of tech.pegasys.teku.infrastructure.ssz.sos.SszReader in project teku by ConsenSys.

the class SszBitlistSchemaImpl method sszDeserializeTree.

@Override
public TreeNode sszDeserializeTree(SszReader reader) {
    int availableBytes = reader.getAvailableBytes();
    // preliminary rough check
    checkSsz((availableBytes - 1) * 8 <= getMaxLength(), "SSZ sequence length exceeds max type length");
    Bytes bytes = reader.read(availableBytes);
    int length = SszBitlistImpl.sszGetLengthAndValidate(bytes);
    if (length > getMaxLength()) {
        throw new SszDeserializeException("Too long bitlist");
    }
    Bytes treeBytes = SszBitlistImpl.sszTruncateLeadingBit(bytes, length);
    try (SszReader sszReader = SszReader.fromBytes(treeBytes)) {
        DeserializedData data = sszDeserializeVector(sszReader);
        return createTree(data.getDataTree(), length);
    }
}
Also used : Bytes(org.apache.tuweni.bytes.Bytes) SszDeserializeException(tech.pegasys.teku.infrastructure.ssz.sos.SszDeserializeException) SszReader(tech.pegasys.teku.infrastructure.ssz.sos.SszReader)

Example 4 with SszReader

use of tech.pegasys.teku.infrastructure.ssz.sos.SszReader in project teku by ConsenSys.

the class AbstractSszCollectionSchema method sszDeserializeFixed.

private DeserializedData sszDeserializeFixed(SszReader reader) {
    int bytesSize = reader.getAvailableBytes();
    checkSsz(bytesSize % getElementSchema().getSszFixedPartSize() == 0, "SSZ sequence length is not multiple of fixed element size");
    int elementBitSize = getSszElementBitSize();
    if (elementBitSize >= 8) {
        checkSsz(bytesSize * 8L / elementBitSize <= getMaxLength(), "SSZ sequence length exceeds max type length");
    } else {
        // preliminary rough check
        checkSsz((bytesSize - 1) * 8L / elementBitSize <= getMaxLength(), "SSZ sequence length exceeds max type length");
    }
    if (getElementSchema() instanceof AbstractSszPrimitiveSchema) {
        int bytesRemain = bytesSize;
        List<LeafNode> childNodes = new ArrayList<>(bytesRemain / LeafNode.MAX_BYTE_SIZE + 1);
        while (bytesRemain > 0) {
            int toRead = min(bytesRemain, LeafNode.MAX_BYTE_SIZE);
            bytesRemain -= toRead;
            Bytes bytes = reader.read(toRead);
            LeafNode node = LeafNode.create(bytes);
            childNodes.add(node);
        }
        Optional<Byte> lastByte;
        if (childNodes.isEmpty()) {
            lastByte = Optional.empty();
        } else {
            Bytes lastNodeData = childNodes.get(childNodes.size() - 1).getData();
            lastByte = Optional.of(lastNodeData.get(lastNodeData.size() - 1));
        }
        return new DeserializedData(TreeUtil.createTree(childNodes, treeDepth()), bytesSize * 8 / elementBitSize, lastByte);
    } else {
        int elementsCount = bytesSize / getElementSchema().getSszFixedPartSize();
        List<TreeNode> childNodes = new ArrayList<>();
        for (int i = 0; i < elementsCount; i++) {
            try (SszReader sszReader = reader.slice(getElementSchema().getSszFixedPartSize())) {
                TreeNode childNode = getElementSchema().sszDeserializeTree(sszReader);
                childNodes.add(childNode);
            }
        }
        return new DeserializedData(TreeUtil.createTree(childNodes, treeDepth()), elementsCount);
    }
}
Also used : Bytes(org.apache.tuweni.bytes.Bytes) SszReader(tech.pegasys.teku.infrastructure.ssz.sos.SszReader) TreeNode(tech.pegasys.teku.infrastructure.ssz.tree.TreeNode) LeafNode(tech.pegasys.teku.infrastructure.ssz.tree.LeafNode) ArrayList(java.util.ArrayList) SszSuperNodeHint(tech.pegasys.teku.infrastructure.ssz.schema.SszSchemaHints.SszSuperNodeHint)

Aggregations

SszReader (tech.pegasys.teku.infrastructure.ssz.sos.SszReader)4 ArrayList (java.util.ArrayList)3 SszDeserializeException (tech.pegasys.teku.infrastructure.ssz.sos.SszDeserializeException)3 TreeNode (tech.pegasys.teku.infrastructure.ssz.tree.TreeNode)3 Bytes (org.apache.tuweni.bytes.Bytes)2 SszSuperNodeHint (tech.pegasys.teku.infrastructure.ssz.schema.SszSchemaHints.SszSuperNodeHint)2 ArrayDeque (java.util.ArrayDeque)1 LeafNode (tech.pegasys.teku.infrastructure.ssz.tree.LeafNode)1