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());
}
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);
}
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);
}
}
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);
}
}
Aggregations