package com.ripple.core.types.known.tx.result; import com.ripple.core.coretypes.STObject; import com.ripple.core.coretypes.hash.Hash256; import com.ripple.core.fields.Field; import com.ripple.core.serialized.SerializedType; import com.ripple.core.serialized.enums.LedgerEntryType; import com.ripple.core.types.known.sle.LedgerEntry; // TODO: fix up this nonsense public class AffectedNode extends STObject { Field field; STObject nested; public AffectedNode(STObject source) { fields = source.getFields(); field = getField(); nested = getNested(); } public boolean isOffer() { return ledgerEntryType() == LedgerEntryType.Offer; } public boolean isAccountRoot() { return ledgerEntryType() == LedgerEntryType.AccountRoot; } public boolean isRippleState() { return ledgerEntryType() == LedgerEntryType.RippleState; } public boolean isDirectoryNode() { return ledgerEntryType() == LedgerEntryType.DirectoryNode; } public boolean wasPreviousNode() { return isDeletedNode() || isModifiedNode(); } public boolean isFinalNode() { return true; } public boolean isCreatedNode() { return field == Field.CreatedNode; } public boolean isDeletedNode() { return field == Field.DeletedNode; } public boolean isModifiedNode() { return field == Field.ModifiedNode; } public Field getField() { return fields.firstKey(); } public Hash256 ledgerIndex() { return nested.get(Hash256.LedgerIndex); } public LedgerEntryType ledgerEntryType() { return ledgerEntryType(nested); } private STObject getNested() { return (STObject) get(getField()); } public LedgerEntry nodeAsPrevious() { return (LedgerEntry) rebuildFromMeta(true); } public LedgerEntry nodeAsFinal() { return (LedgerEntry) rebuildFromMeta(false); } public STObject rebuildFromMeta(boolean layerPrevious) { STObject mixed = new STObject(); boolean created = isCreatedNode(); Field wrapperField = created ? Field.CreatedNode : isDeletedNode() ? Field.DeletedNode : Field.ModifiedNode; STObject wrapped = (STObject) get(wrapperField); Field finalFields = created ? Field.NewFields : Field.FinalFields; if (!wrapped.has(finalFields)) { STObject source = new STObject(wrapped.getFields()); source.put(Hash256.index, wrapped.get(Hash256.LedgerIndex)); return STObject.formatted(source); } STObject finals = (STObject) wrapped.get(finalFields); for (Field field : finals) { mixed.put(field, finals.get(field)); } // DirectoryNode LedgerEntryType won't have `PreviousFields` if (layerPrevious && wrapped.has(Field.PreviousFields)) { STObject previous = wrapped.get(STObject.PreviousFields); STObject changed = new STObject(); mixed.put(Field.FinalFields, changed); for (Field field : previous) { mixed.put(field, previous.get(field)); changed.put(field, finals.get(field)); } } for (Field field : wrapped) { switch (field) { case NewFields: case PreviousFields: case FinalFields: continue; default: SerializedType value = wrapped.get(field); if (field == Field.LedgerIndex) { field = Field.index; } mixed.put(field, value); } } return STObject.formatted(mixed); } public static boolean isAffectedNode(STObject source) { return (source.size() == 1 && ( source.has(DeletedNode) || source.has(CreatedNode) || source.has(ModifiedNode))); } }