All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.nem.symbol.catapult.builders.AccountStateBuilder Maven / Gradle / Ivy

/**
*** Copyright (c) 2016-present,
*** Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp. All rights reserved.
***
*** This file is part of Catapult.
***
*** Catapult is free software: you can redistribute it and/or modify
*** it under the terms of the GNU Lesser General Public License as published by
*** the Free Software Foundation, either version 3 of the License, or
*** (at your option) any later version.
***
*** Catapult is distributed in the hope that it will be useful,
*** but WITHOUT ANY WARRANTY; without even the implied warranty of
*** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*** GNU Lesser General Public License for more details.
***
*** You should have received a copy of the GNU Lesser General Public License
*** along with Catapult. If not, see .
**/

package io.nem.symbol.catapult.builders;

import java.io.DataInputStream;
import java.nio.ByteBuffer;
import java.util.EnumSet;
import java.util.List;

/**
* Binary layout for non-historical account state
**/
public class AccountStateBuilder implements Serializer {

    /** Address of account. **/
    private final AddressDto address;

    /** Height at which address has been obtained. **/
    private final HeightDto addressHeight;

    /** Public key of account. **/
    private final KeyDto publicKey;

    /** Height at which public key has been obtained. **/
    private final HeightDto publicKeyHeight;

    /** Type of account. **/
    private final AccountTypeDto accountType;

    /** Account format. **/
    private final AccountStateFormatDto format;

    /** Mask of supplemental account key flags. **/
    private final EnumSet supplementalAccountKeysMask;

    /** Linked account public key. **/
    private KeyDto linkedPublicKey;

    /** Vrf public key. **/
    private KeyDto vrfPublicKey;

    /** Voting public key. **/
    private VotingKeyDto votingPublicKey;

    /** Node public key. **/
    private KeyDto nodePublicKey;

    /** Current importance snapshot of the account. **/
    private ImportanceSnapshotBuilder importanceSnapshots;

    /** Activity buckets of the account. **/
    private HeightActivityBucketsBuilder activityBuckets;

    /** Balances of account. **/
    private final List balances;

    /**
     * Constructor - Creates an object from stream.
     *
     * @param stream Byte stream to use to serialize the object.
     */
    protected AccountStateBuilder(DataInputStream stream) {
        try {
            this.address = AddressDto.loadFromBinary(stream);
            this.addressHeight = HeightDto.loadFromBinary(stream);
            this.publicKey = KeyDto.loadFromBinary(stream);
            this.publicKeyHeight = HeightDto.loadFromBinary(stream);
            this.accountType = AccountTypeDto.loadFromBinary(stream);
            this.format = AccountStateFormatDto.loadFromBinary(stream);
            this.supplementalAccountKeysMask = GeneratorUtils.toSet(AccountKeyFlagsDto.class, stream.readByte());
            final short balancesCount = Short.reverseBytes(stream.readShort());
            this.balances = GeneratorUtils.loadFromBinaryArray(MosaicBuilder::loadFromBinary, stream, balancesCount);
            if (this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.LINKED)) {
                this.linkedPublicKey = KeyDto.loadFromBinary(stream);
            }
            if (this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.VRF)) {
                this.vrfPublicKey = KeyDto.loadFromBinary(stream);
            }
            if (this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.VOTING)) {
                this.votingPublicKey = VotingKeyDto.loadFromBinary(stream);
            }
            if (this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.NODE)) {
                this.nodePublicKey = KeyDto.loadFromBinary(stream);
            }
            if (this.format == AccountStateFormatDto.HIGH_VALUE) {
                this.importanceSnapshots = ImportanceSnapshotBuilder.loadFromBinary(stream);
            }
            if (this.format == AccountStateFormatDto.HIGH_VALUE) {
                this.activityBuckets = HeightActivityBucketsBuilder.loadFromBinary(stream);
            }
        } catch (Exception e) {
            throw GeneratorUtils.getExceptionToPropagate(e);
        }
    }

    /**
     * Creates an instance of AccountStateBuilder from a stream.
     *
     * @param stream Byte stream to use to serialize the object.
     * @return Instance of AccountStateBuilder.
     */
    public static AccountStateBuilder loadFromBinary(DataInputStream stream) {
        return new AccountStateBuilder(stream);
    }
    
    /**
    * Constructor.
    *
    * @param address Address of account.
    * @param addressHeight Height at which address has been obtained.
    * @param publicKey Public key of account.
    * @param publicKeyHeight Height at which public key has been obtained.
    * @param accountType Type of account.
    * @param format Account format.
    * @param supplementalAccountKeysMask Mask of supplemental account key flags.
    * @param linkedPublicKey Linked account public key.
    * @param vrfPublicKey Vrf public key.
    * @param votingPublicKey Voting public key.
    * @param nodePublicKey Node public key.
    * @param importanceSnapshots Current importance snapshot of the account.
    * @param activityBuckets Activity buckets of the account.
    * @param balances Balances of account.
    */
    protected AccountStateBuilder(AddressDto address, HeightDto addressHeight, KeyDto publicKey, HeightDto publicKeyHeight, AccountTypeDto accountType, AccountStateFormatDto format, EnumSet supplementalAccountKeysMask, KeyDto linkedPublicKey, KeyDto vrfPublicKey, VotingKeyDto votingPublicKey, KeyDto nodePublicKey, ImportanceSnapshotBuilder importanceSnapshots, HeightActivityBucketsBuilder activityBuckets, List balances) {
        GeneratorUtils.notNull(address, "address is null");
        GeneratorUtils.notNull(addressHeight, "addressHeight is null");
        GeneratorUtils.notNull(publicKey, "publicKey is null");
        GeneratorUtils.notNull(publicKeyHeight, "publicKeyHeight is null");
        GeneratorUtils.notNull(accountType, "accountType is null");
        GeneratorUtils.notNull(format, "format is null");
        GeneratorUtils.notNull(supplementalAccountKeysMask, "supplementalAccountKeysMask is null");
        if (supplementalAccountKeysMask.contains(AccountKeyFlagsDto.LINKED)) {
            GeneratorUtils.notNull(linkedPublicKey, "linkedPublicKey is null");
        }
        if (supplementalAccountKeysMask.contains(AccountKeyFlagsDto.VRF)) {
            GeneratorUtils.notNull(vrfPublicKey, "vrfPublicKey is null");
        }
        if (supplementalAccountKeysMask.contains(AccountKeyFlagsDto.VOTING)) {
            GeneratorUtils.notNull(votingPublicKey, "votingPublicKey is null");
        }
        if (supplementalAccountKeysMask.contains(AccountKeyFlagsDto.NODE)) {
            GeneratorUtils.notNull(nodePublicKey, "nodePublicKey is null");
        }
        if (format == AccountStateFormatDto.HIGH_VALUE) {
            GeneratorUtils.notNull(importanceSnapshots, "importanceSnapshots is null");
        }
        if (format == AccountStateFormatDto.HIGH_VALUE) {
            GeneratorUtils.notNull(activityBuckets, "activityBuckets is null");
        }
        GeneratorUtils.notNull(balances, "balances is null");
        this.address = address;
        this.addressHeight = addressHeight;
        this.publicKey = publicKey;
        this.publicKeyHeight = publicKeyHeight;
        this.accountType = accountType;
        this.format = format;
        this.supplementalAccountKeysMask = supplementalAccountKeysMask;
        this.linkedPublicKey = linkedPublicKey;
        this.vrfPublicKey = vrfPublicKey;
        this.votingPublicKey = votingPublicKey;
        this.nodePublicKey = nodePublicKey;
        this.importanceSnapshots = importanceSnapshots;
        this.activityBuckets = activityBuckets;
        this.balances = balances;
    }
    
    /**
     * Creates an instance of AccountStateBuilder.
     *
     * @param address Address of account.
     * @param addressHeight Height at which address has been obtained.
     * @param publicKey Public key of account.
     * @param publicKeyHeight Height at which public key has been obtained.
     * @param accountType Type of account.
     * @param supplementalAccountKeysMask Mask of supplemental account key flags.
     * @param linkedPublicKey Linked account public key.
     * @param vrfPublicKey Vrf public key.
     * @param votingPublicKey Voting public key.
     * @param nodePublicKey Node public key.
     * @param balances Balances of account.
     * @return Instance of AccountStateBuilder.
     */
    public static AccountStateBuilder createRegular(AddressDto address, HeightDto addressHeight, KeyDto publicKey, HeightDto publicKeyHeight, AccountTypeDto accountType, EnumSet supplementalAccountKeysMask, KeyDto linkedPublicKey, KeyDto vrfPublicKey, VotingKeyDto votingPublicKey, KeyDto nodePublicKey, List balances) {
        AccountStateFormatDto format = AccountStateFormatDto.REGULAR;
        return new AccountStateBuilder(address, addressHeight, publicKey, publicKeyHeight, accountType, format, supplementalAccountKeysMask, linkedPublicKey, vrfPublicKey, votingPublicKey, nodePublicKey, null, null, balances);
    }
    
    /**
     * Creates an instance of AccountStateBuilder.
     *
     * @param address Address of account.
     * @param addressHeight Height at which address has been obtained.
     * @param publicKey Public key of account.
     * @param publicKeyHeight Height at which public key has been obtained.
     * @param accountType Type of account.
     * @param supplementalAccountKeysMask Mask of supplemental account key flags.
     * @param linkedPublicKey Linked account public key.
     * @param vrfPublicKey Vrf public key.
     * @param votingPublicKey Voting public key.
     * @param nodePublicKey Node public key.
     * @param importanceSnapshots Current importance snapshot of the account.
     * @param activityBuckets Activity buckets of the account.
     * @param balances Balances of account.
     * @return Instance of AccountStateBuilder.
     */
    public static AccountStateBuilder createHighValue(AddressDto address, HeightDto addressHeight, KeyDto publicKey, HeightDto publicKeyHeight, AccountTypeDto accountType, EnumSet supplementalAccountKeysMask, KeyDto linkedPublicKey, KeyDto vrfPublicKey, VotingKeyDto votingPublicKey, KeyDto nodePublicKey, ImportanceSnapshotBuilder importanceSnapshots, HeightActivityBucketsBuilder activityBuckets, List balances) {
        AccountStateFormatDto format = AccountStateFormatDto.HIGH_VALUE;
        return new AccountStateBuilder(address, addressHeight, publicKey, publicKeyHeight, accountType, format, supplementalAccountKeysMask, linkedPublicKey, vrfPublicKey, votingPublicKey, nodePublicKey, importanceSnapshots, activityBuckets, balances);
    }

    /**
     * Gets address of account.
     *
     * @return Address of account.
     */
    public AddressDto getAddress() {
        return this.address;
    }

    /**
     * Gets height at which address has been obtained.
     *
     * @return Height at which address has been obtained.
     */
    public HeightDto getAddressHeight() {
        return this.addressHeight;
    }

    /**
     * Gets public key of account.
     *
     * @return Public key of account.
     */
    public KeyDto getPublicKey() {
        return this.publicKey;
    }

    /**
     * Gets height at which public key has been obtained.
     *
     * @return Height at which public key has been obtained.
     */
    public HeightDto getPublicKeyHeight() {
        return this.publicKeyHeight;
    }

    /**
     * Gets type of account.
     *
     * @return Type of account.
     */
    public AccountTypeDto getAccountType() {
        return this.accountType;
    }

    /**
     * Gets account format.
     *
     * @return Account format.
     */
    public AccountStateFormatDto getFormat() {
        return this.format;
    }

    /**
     * Gets mask of supplemental account key flags.
     *
     * @return Mask of supplemental account key flags.
     */
    public EnumSet getSupplementalAccountKeysMask() {
        return this.supplementalAccountKeysMask;
    }

    /**
     * Gets linked account public key.
     *
     * @return Linked account public key.
     */
    public KeyDto getLinkedPublicKey() {
        if (!(this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.LINKED))) {
            throw new java.lang.IllegalStateException("supplementalAccountKeysMask is not set to LINKED.");
        }
        return this.linkedPublicKey;
    }

    /**
     * Gets vrf public key.
     *
     * @return Vrf public key.
     */
    public KeyDto getVrfPublicKey() {
        if (!(this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.VRF))) {
            throw new java.lang.IllegalStateException("supplementalAccountKeysMask is not set to VRF.");
        }
        return this.vrfPublicKey;
    }

    /**
     * Gets voting public key.
     *
     * @return Voting public key.
     */
    public VotingKeyDto getVotingPublicKey() {
        if (!(this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.VOTING))) {
            throw new java.lang.IllegalStateException("supplementalAccountKeysMask is not set to VOTING.");
        }
        return this.votingPublicKey;
    }

    /**
     * Gets node public key.
     *
     * @return Node public key.
     */
    public KeyDto getNodePublicKey() {
        if (!(this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.NODE))) {
            throw new java.lang.IllegalStateException("supplementalAccountKeysMask is not set to NODE.");
        }
        return this.nodePublicKey;
    }

    /**
     * Gets current importance snapshot of the account.
     *
     * @return Current importance snapshot of the account.
     */
    public ImportanceSnapshotBuilder getImportanceSnapshots() {
        if (!(this.format == AccountStateFormatDto.HIGH_VALUE)) {
            throw new java.lang.IllegalStateException("format is not set to HIGH_VALUE.");
        }
        return this.importanceSnapshots;
    }

    /**
     * Gets activity buckets of the account.
     *
     * @return Activity buckets of the account.
     */
    public HeightActivityBucketsBuilder getActivityBuckets() {
        if (!(this.format == AccountStateFormatDto.HIGH_VALUE)) {
            throw new java.lang.IllegalStateException("format is not set to HIGH_VALUE.");
        }
        return this.activityBuckets;
    }

    /**
     * Gets balances of account.
     *
     * @return Balances of account.
     */
    public List getBalances() {
        return this.balances;
    }


    /**
     * Gets the size of the object.
     *
     * @return Size in bytes.
     */
    public int getSize() {
        int size = 0;
        size += this.address.getSize();
        size += this.addressHeight.getSize();
        size += this.publicKey.getSize();
        size += this.publicKeyHeight.getSize();
        size += this.accountType.getSize();
        size += this.format.getSize();
        size += AccountKeyFlagsDto.values()[0].getSize();
        if (this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.LINKED)) {
            size += this.linkedPublicKey.getSize();
        }
        if (this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.VRF)) {
            size += this.vrfPublicKey.getSize();
        }
        if (this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.VOTING)) {
            size += this.votingPublicKey.getSize();
        }
        if (this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.NODE)) {
            size += this.nodePublicKey.getSize();
        }
        if (this.format == AccountStateFormatDto.HIGH_VALUE) {
            size += this.importanceSnapshots.getSize();
        }
        if (this.format == AccountStateFormatDto.HIGH_VALUE) {
            size += this.activityBuckets.getSize();
        }
        size += 2; // balancesCount
        size += this.balances.stream().mapToInt(o -> o.getSize()).sum();
        return size;
    }



    /**
     * Serializes an object to bytes.
     *
     * @return Serialized bytes.
     */
    public byte[] serialize() {
        return GeneratorUtils.serialize((dataOutputStream) -> {
            GeneratorUtils.writeEntity(dataOutputStream, this.address);
            GeneratorUtils.writeEntity(dataOutputStream, this.addressHeight);
            GeneratorUtils.writeEntity(dataOutputStream, this.publicKey);
            GeneratorUtils.writeEntity(dataOutputStream, this.publicKeyHeight);
            GeneratorUtils.writeEntity(dataOutputStream, this.accountType);
            GeneratorUtils.writeEntity(dataOutputStream, this.format);
            dataOutputStream.writeByte((byte) GeneratorUtils.toLong(AccountKeyFlagsDto.class, this.supplementalAccountKeysMask));
            if (this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.LINKED)) {
                GeneratorUtils.writeEntity(dataOutputStream, this.linkedPublicKey);
            }
            if (this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.VRF)) {
                GeneratorUtils.writeEntity(dataOutputStream, this.vrfPublicKey);
            }
            if (this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.VOTING)) {
                GeneratorUtils.writeEntity(dataOutputStream, this.votingPublicKey);
            }
            if (this.supplementalAccountKeysMask.contains(AccountKeyFlagsDto.NODE)) {
                GeneratorUtils.writeEntity(dataOutputStream, this.nodePublicKey);
            }
            if (this.format == AccountStateFormatDto.HIGH_VALUE) {
                GeneratorUtils.writeEntity(dataOutputStream, this.importanceSnapshots);
            }
            if (this.format == AccountStateFormatDto.HIGH_VALUE) {
                GeneratorUtils.writeEntity(dataOutputStream, this.activityBuckets);
            }
            dataOutputStream.writeShort(Short.reverseBytes((short) GeneratorUtils.getSize(this.getBalances())));
            GeneratorUtils.writeList(dataOutputStream, this.balances);
        });
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy