
io.nem.sdk.infrastructure.BinarySerializationImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sdk-core Show documentation
Show all versions of sdk-core Show documentation
sdk-core lib for NEM2 sdk Java
The newest version!
/*
* Copyright 2019 NEM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.nem.sdk.infrastructure;
import io.nem.catapult.builders.AccountAddressRestrictionTransactionBodyBuilder;
import io.nem.catapult.builders.AccountLinkActionDto;
import io.nem.catapult.builders.AccountLinkTransactionBodyBuilder;
import io.nem.catapult.builders.AccountMetadataTransactionBodyBuilder;
import io.nem.catapult.builders.AccountMosaicRestrictionTransactionBodyBuilder;
import io.nem.catapult.builders.AccountOperationRestrictionTransactionBodyBuilder;
import io.nem.catapult.builders.AccountRestrictionFlagsDto;
import io.nem.catapult.builders.AddressAliasTransactionBodyBuilder;
import io.nem.catapult.builders.AddressDto;
import io.nem.catapult.builders.AggregateTransactionBodyBuilder;
import io.nem.catapult.builders.AliasActionDto;
import io.nem.catapult.builders.AmountDto;
import io.nem.catapult.builders.BlockDurationDto;
import io.nem.catapult.builders.CosignatureBuilder;
import io.nem.catapult.builders.EmbeddedTransactionBuilder;
import io.nem.catapult.builders.EntityTypeDto;
import io.nem.catapult.builders.Hash256Dto;
import io.nem.catapult.builders.HashLockTransactionBodyBuilder;
import io.nem.catapult.builders.KeyDto;
import io.nem.catapult.builders.LockHashAlgorithmDto;
import io.nem.catapult.builders.MosaicAddressRestrictionTransactionBodyBuilder;
import io.nem.catapult.builders.MosaicAliasTransactionBodyBuilder;
import io.nem.catapult.builders.MosaicDefinitionTransactionBodyBuilder;
import io.nem.catapult.builders.MosaicFlagsDto;
import io.nem.catapult.builders.MosaicGlobalRestrictionTransactionBodyBuilder;
import io.nem.catapult.builders.MosaicIdDto;
import io.nem.catapult.builders.MosaicMetadataTransactionBodyBuilder;
import io.nem.catapult.builders.MosaicNonceDto;
import io.nem.catapult.builders.MosaicRestrictionTypeDto;
import io.nem.catapult.builders.MosaicSupplyChangeActionDto;
import io.nem.catapult.builders.MosaicSupplyChangeTransactionBodyBuilder;
import io.nem.catapult.builders.MultisigAccountModificationTransactionBodyBuilder;
import io.nem.catapult.builders.NamespaceIdDto;
import io.nem.catapult.builders.NamespaceMetadataTransactionBodyBuilder;
import io.nem.catapult.builders.NamespaceRegistrationTransactionBodyBuilder;
import io.nem.catapult.builders.NetworkTypeDto;
import io.nem.catapult.builders.SecretLockTransactionBodyBuilder;
import io.nem.catapult.builders.SecretProofTransactionBodyBuilder;
import io.nem.catapult.builders.Serializer;
import io.nem.catapult.builders.SignatureDto;
import io.nem.catapult.builders.TimestampDto;
import io.nem.catapult.builders.TransactionBuilder;
import io.nem.catapult.builders.TransactionBuilderFactory;
import io.nem.catapult.builders.TransferTransactionBodyBuilder;
import io.nem.catapult.builders.UnresolvedAddressDto;
import io.nem.catapult.builders.UnresolvedMosaicBuilder;
import io.nem.catapult.builders.UnresolvedMosaicIdDto;
import io.nem.core.utils.ConvertUtils;
import io.nem.core.utils.ExceptionUtils;
import io.nem.core.utils.StringEncoder;
import io.nem.sdk.api.BinarySerialization;
import io.nem.sdk.model.account.Address;
import io.nem.sdk.model.account.PublicAccount;
import io.nem.sdk.model.account.UnresolvedAddress;
import io.nem.sdk.model.blockchain.BlockDuration;
import io.nem.sdk.model.blockchain.NetworkType;
import io.nem.sdk.model.message.Message;
import io.nem.sdk.model.message.MessageType;
import io.nem.sdk.model.mosaic.Mosaic;
import io.nem.sdk.model.mosaic.MosaicFlags;
import io.nem.sdk.model.mosaic.MosaicId;
import io.nem.sdk.model.mosaic.MosaicNonce;
import io.nem.sdk.model.mosaic.MosaicSupplyChangeActionType;
import io.nem.sdk.model.mosaic.UnresolvedMosaicId;
import io.nem.sdk.model.namespace.AliasAction;
import io.nem.sdk.model.namespace.NamespaceId;
import io.nem.sdk.model.namespace.NamespaceRegistrationType;
import io.nem.sdk.model.transaction.AccountAddressRestrictionTransaction;
import io.nem.sdk.model.transaction.AccountAddressRestrictionTransactionFactory;
import io.nem.sdk.model.transaction.AccountLinkAction;
import io.nem.sdk.model.transaction.AccountLinkTransaction;
import io.nem.sdk.model.transaction.AccountLinkTransactionFactory;
import io.nem.sdk.model.transaction.AccountMetadataTransaction;
import io.nem.sdk.model.transaction.AccountMetadataTransactionFactory;
import io.nem.sdk.model.transaction.AccountMosaicRestrictionTransaction;
import io.nem.sdk.model.transaction.AccountMosaicRestrictionTransactionFactory;
import io.nem.sdk.model.transaction.AccountOperationRestrictionTransaction;
import io.nem.sdk.model.transaction.AccountOperationRestrictionTransactionFactory;
import io.nem.sdk.model.transaction.AccountRestrictionFlags;
import io.nem.sdk.model.transaction.AddressAliasTransaction;
import io.nem.sdk.model.transaction.AddressAliasTransactionFactory;
import io.nem.sdk.model.transaction.AggregateTransaction;
import io.nem.sdk.model.transaction.AggregateTransactionCosignature;
import io.nem.sdk.model.transaction.AggregateTransactionFactory;
import io.nem.sdk.model.transaction.Deadline;
import io.nem.sdk.model.transaction.HashLockTransaction;
import io.nem.sdk.model.transaction.HashLockTransactionFactory;
import io.nem.sdk.model.transaction.LockHashAlgorithmType;
import io.nem.sdk.model.transaction.MetadataTransaction;
import io.nem.sdk.model.transaction.MosaicAddressRestrictionTransaction;
import io.nem.sdk.model.transaction.MosaicAddressRestrictionTransactionFactory;
import io.nem.sdk.model.transaction.MosaicAliasTransaction;
import io.nem.sdk.model.transaction.MosaicAliasTransactionFactory;
import io.nem.sdk.model.transaction.MosaicDefinitionTransaction;
import io.nem.sdk.model.transaction.MosaicDefinitionTransactionFactory;
import io.nem.sdk.model.transaction.MosaicGlobalRestrictionTransaction;
import io.nem.sdk.model.transaction.MosaicGlobalRestrictionTransactionFactory;
import io.nem.sdk.model.transaction.MosaicMetadataTransaction;
import io.nem.sdk.model.transaction.MosaicMetadataTransactionFactory;
import io.nem.sdk.model.transaction.MosaicRestrictionType;
import io.nem.sdk.model.transaction.MosaicSupplyChangeTransaction;
import io.nem.sdk.model.transaction.MosaicSupplyChangeTransactionFactory;
import io.nem.sdk.model.transaction.MultisigAccountModificationTransaction;
import io.nem.sdk.model.transaction.MultisigAccountModificationTransactionFactory;
import io.nem.sdk.model.transaction.NamespaceMetadataTransaction;
import io.nem.sdk.model.transaction.NamespaceMetadataTransactionFactory;
import io.nem.sdk.model.transaction.NamespaceRegistrationTransaction;
import io.nem.sdk.model.transaction.NamespaceRegistrationTransactionFactory;
import io.nem.sdk.model.transaction.SecretLockTransaction;
import io.nem.sdk.model.transaction.SecretLockTransactionFactory;
import io.nem.sdk.model.transaction.SecretProofTransaction;
import io.nem.sdk.model.transaction.SecretProofTransactionFactory;
import io.nem.sdk.model.transaction.Transaction;
import io.nem.sdk.model.transaction.TransactionFactory;
import io.nem.sdk.model.transaction.TransactionType;
import io.nem.sdk.model.transaction.TransferTransaction;
import io.nem.sdk.model.transaction.TransferTransactionFactory;
import java.io.DataInputStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.Validate;
import org.bouncycastle.util.encoders.Hex;
/**
* Implementation of BinarySerialization. It uses the catbuffer generated builders to deserialize an
* object.
*/
public class BinarySerializationImpl implements BinarySerialization {
/**
* Cached instance.
*/
public static final BinarySerialization INSTANCE = new BinarySerializationImpl();
/**
* The serializers, one per {@link TransactionType} must be registered.
*/
private final Map> serializers = new EnumMap<>(
TransactionType.class);
/**
* Constructor
*/
public BinarySerializationImpl() {
register(new TransferTransactionSerializer());
register(new MosaicSupplyChangeTransactionSerializer());
register(new MosaicDefinitionTransactionSerializer());
register(new AccountLinkTransactionSerializer());
register(new AccountMetadataTransactionSerializer());
register(new MosaicMetadataTransactionSerializer());
register(new NamespaceMetadataTransactionSerializer());
register(new NamespaceRegistrationTransactionSerializer());
register(new SecretLockTransactionSerializer());
register(new SecretProofTransactionSerializer());
register(new AddressAliasTransactionSerializer());
register(new MosaicAliasTransactionSerializer());
register(new HashLockTransactionSerializer());
register(new MultisigAccountModificationTransactionSerializer());
register(new MosaicAddressRestrictionTransactionSerializer());
register(new MosaicGlobalRestrictionTransactionSerializer());
register(new AccountMosaicRestrictionTransactionSerializer());
register(new AccountOperationRestrictionTransactionSerializer());
register(new AccountAddressRestrictionTransactionSerializer());
register(new AggregateTransactionSerializer(TransactionType.AGGREGATE_COMPLETE, this));
register(new AggregateTransactionSerializer(TransactionType.AGGREGATE_BONDED, this));
}
/**
* @param serializer the serializer to be registered.
*/
private void register(TransactionSerializer serializer) {
if (serializers.put(serializer.getTransactionType(), serializer) != null) {
throw new IllegalArgumentException(
"TransactionSerializer for type " + serializer.getTransactionType()
+ " was already registered!");
}
}
/**
* It returns the registered {@link TransactionSerializer} for the given {@link
* TransactionType}.
*
* @param transactionType the transaction type.
* @param the transaction type
* @return the {@link TransactionSerializer}
*/
TransactionSerializer resolveSerializer(
TransactionType transactionType) {
@SuppressWarnings("unchecked")
TransactionSerializer mapper = (TransactionSerializer) serializers
.get(transactionType);
if (mapper == null) {
throw new UnsupportedOperationException(
"Unimplemented Transaction type " + transactionType);
}
return mapper;
}
/**
* Serialization basic implementation, it just delegates the work to the transactions.
*
* @param transaction the transaction
* @return the serialized transaction.
*/
@Override
public byte[] serialize(T transaction) {
Validate.notNull(transaction, "Transaction must not be null");
TransactionBuilder transactionBuilder = getTransactionBuilder(transaction);
return serializeTransaction(transactionBuilder.serialize(), transaction);
}
/**
* Serialized the transfer transaction to embedded bytes.
*
* @param transaction the transaction
* @param the transaction class
* @return bytes of the transaction.
*/
public byte[] serializeEmbedded(T transaction) {
Validate.notNull(transaction, "Transaction must not be null");
EmbeddedTransactionBuilder embeddedTransactionBuilder = EmbeddedTransactionBuilder.create(
new KeyDto(getRequiredSignerBytes(transaction.getSigner())),
transaction.getVersion().byteValue(),
NetworkTypeDto.rawValueOf((byte) transaction.getNetworkType().getValue()),
EntityTypeDto.rawValueOf((short) transaction.getType().getValue()));
return serializeTransaction(embeddedTransactionBuilder.serialize(), transaction);
}
/**
* Creates the right {@link EmbeddedTransactionBuilder} from the transaction
*
* @param transaction the transaction
* @param the transaction class
* @return the {@link EmbeddedTransactionBuilder}
*/
private EmbeddedTransactionBuilder toEmbeddedTransactionBuilder(
T transaction) {
return TransactionBuilderFactory.createEmbeddedTransactionBuilder(
SerializationUtils.toDataInput(serializeEmbedded(transaction)));
}
/**
* Gets the top level {@link TransactionBuilder} for the given transaction
*
* @param transaction the transaction
* @return the top level {@link TransactionBuilder}
*/
private TransactionBuilder getTransactionBuilder(Transaction transaction) {
final SignatureDto signatureDto = transaction.getSignature()
.map(SerializationUtils::toSignatureDto)
.orElseGet(() -> new SignatureDto(ByteBuffer.allocate(64)));
final ByteBuffer signerBuffer = transaction.getSigner()
.map(SerializationUtils::toByteBuffer).orElseGet(() -> ByteBuffer.allocate(32));
return TransactionBuilder.create(
signatureDto,
new KeyDto(signerBuffer),
transaction.getVersion().byteValue(),
NetworkTypeDto.rawValueOf((byte) transaction.getNetworkType().getValue()),
EntityTypeDto.rawValueOf((short) transaction.getType().getValue()),
new AmountDto(transaction.getMaxFee().longValue()),
new TimestampDto(transaction.getDeadline().getInstant()));
}
/**
* This method concats the common bytes to the serialized specific transaction.
*
* @param the type of the transaction
* @param commonBytes the common byte array.
* @param transaction the transaction.
* @return the serialized transaction.
*/
private byte[] serializeTransaction(byte[] commonBytes, T transaction) {
TransactionSerializer transactionSerializer = resolveSerializer(transaction.getType());
Validate.isTrue(
transactionSerializer.getTransactionClass().isAssignableFrom(transaction.getClass()),
"Invalid TransactionSerializer's transaction class.");
byte[] transactionBytes = transactionSerializer.toBodyBuilder(transaction).serialize();
return SerializationUtils.concat(commonBytes, transactionBytes);
}
/**
* It returns the transaction's byte array size useful to calculate its fee.
*
* @param the type of the transaction
* @param transaction the transaction
* @return the size of the transaction.
*/
@Override
public int getSize(T transaction) {
return getTransactionBuilder(transaction).getSize() + resolveSerializer(
transaction.getType()).toBodyBuilder(transaction)
.getSize();
}
/**
* Returns the transaction creator public account.
*
* @return the signer public account
*/
private ByteBuffer getRequiredSignerBytes(Optional signer) {
return signer.map(SerializationUtils::toByteBuffer)
.orElseThrow(() -> new IllegalStateException("SignerBytes is required"));
}
/**
* Deserialization of transactions. All the code related to the deserialization is handled in
* the class and its helpers. Transaction Model Objects are not polluted with deserialization
* functionality.
*
* @param payload the byte array payload
* @return the {@link Transaction}
*/
@Override
@SuppressWarnings("squid:S1192")
public Transaction deserialize(byte[] payload) {
Validate.notNull(payload, "Payload must not be null");
DataInputStream stream = SerializationUtils.toDataInput(payload);
TransactionBuilder builder = TransactionBuilderFactory
.createTransactionBuilder(stream);
return toTransaction(builder);
}
/**
* It converts a {@link TransactionBuilder} to a {@link Transaction}
*
* @param builder the builder
* @return the {@link Transaction} model.
*/
private Transaction toTransaction(TransactionBuilder builder) {
TransactionType transactionType = TransactionType
.rawValueOf(SerializationUtils.shortToUnsignedInt(builder.getType().getValue()));
NetworkType networkType = NetworkType
.rawValueOf(SerializationUtils.byteToUnsignedInt(builder.getNetwork().getValue()));
Deadline deadline = new Deadline(
SerializationUtils.toUnsignedBigInteger(builder.getDeadline().getTimestamp()));
TransactionFactory> factory = resolveSerializer(transactionType)
.fromBodyBuilder(networkType, builder.getBody());
factory.version(SerializationUtils.byteToUnsignedInt(builder.getVersion()));
factory.maxFee(SerializationUtils.toUnsignedBigInteger(builder.getFee()));
factory.deadline(deadline);
if (!areAllZeros(builder.getSignature().getSignature().array())) {
factory
.signature(SerializationUtils.toHexString(builder.getSignature().getSignature()));
}
if (!areAllZeros(builder.getSignerPublicKey().getKey().array())) {
factory.signer(
SerializationUtils.toPublicAccount(builder.getSignerPublicKey(), networkType));
}
return factory.build();
}
/**
* @param array the byte array.
* @return if all the values in the array are zeros
*/
private boolean areAllZeros(byte[] array) {
for (byte b : array) {
if (b != 0) {
return false;
}
}
return true;
}
/**
* It deserializes a payload of a embedded transaction into a transact model.
*
* @param payload the payload as {@link DataInputStream}
* @return the {@link Transaction} model.
*/
public Transaction deserializeEmbedded(DataInputStream payload) {
return ExceptionUtils.propagate(() -> {
Validate.notNull(payload, "Payload must not be null");
EmbeddedTransactionBuilder builder = TransactionBuilderFactory
.createEmbeddedTransactionBuilder(payload);
return toTransaction(builder);
});
}
/**
* It converts a {@link EmbeddedTransactionBuilder} to a {@link Transaction}
*
* @param builder the builder
* @return the {@link Transaction} model.
*/
private Transaction toTransaction(EmbeddedTransactionBuilder builder) {
TransactionType transactionType = TransactionType
.rawValueOf(SerializationUtils.shortToUnsignedInt(builder.getType().getValue()));
NetworkType networkType = NetworkType
.rawValueOf(SerializationUtils.byteToUnsignedInt(builder.getNetwork().getValue()));
TransactionFactory> factory = resolveSerializer(transactionType)
.fromBodyBuilder(networkType, builder.getBody());
factory
.signer(
SerializationUtils.toPublicAccount(builder.getSignerPublicKey(), networkType));
factory.version(SerializationUtils.byteToUnsignedInt(builder.getVersion()));
return factory.build();
}
/**
* Interface of the serializer helper classes that know how to serialize/deserialize one type of
* transaction from a payload.
*/
interface TransactionSerializer {
/**
* @return the {@link TransactionType} of the transaction this helper handles.
*/
TransactionType getTransactionType();
/**
* @return the transaction class this serializer handles.
*/
Class getTransactionClass();
/**
* Subclasses would need to create the {@link TransactionFactory} for the handled {@link
* TransactionType} with just the specific transaction values. Common values like maxFee and
* deadline are handled at top level, subclasses won't need to duplicate the deserialization
* efforts.
*
* @param networkType the network type
* @param transactionBuilder the stream containing just the specific transaction values in
* the right order.
* @return the TransactionFactory of the transaction type this object handles.
*/
TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder);
/**
* Subclasses would need to know how to serialize the internal components of a transaction,
* the bytes that are serialized after the common attributes like max fee and duration.
* Subclasses would use catbuffer's transaction body builders.
*
* @param transaction the transaction to be serialized
* @return the catbuffer {@link Serializer}.
*/
Serializer toBodyBuilder(T transaction);
}
private static class TransferTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.TRANSFER;
}
@Override
public Class getTransactionClass() {
return TransferTransaction.class;
}
@Override
public TransactionFactory> fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
TransferTransactionBodyBuilder builder = ((TransferTransactionBodyBuilder) transactionBuilder);
byte[] messageArray = builder.getMessage().array();
MessageType messageType = MessageType
.rawValueOf(SerializationUtils.byteToUnsignedInt(messageArray[0]));
String messageHex = ConvertUtils.toHex(messageArray).substring(2);
UnresolvedAddress recipient = SerializationUtils
.toUnresolvedAddress(builder.getRecipientAddress());
List mosaics = builder.getMosaics().stream()
.map(SerializationUtils::toMosaic)
.collect(Collectors.toList());
Message message = Message.createFromPayload(messageType, messageHex);
return TransferTransactionFactory.create(networkType,
recipient, mosaics, message);
}
@Override
public Serializer toBodyBuilder(TransferTransaction transaction) {
return TransferTransactionBodyBuilder.create(
new UnresolvedAddressDto(
SerializationUtils
.fromUnresolvedAddressToByteBuffer(transaction.getRecipient(),
transaction.getNetworkType())),
getUnresolvedMosaicArray(transaction),
getMessageBuffer(transaction));
}
/**
* Gets mosaic array.
*
* @return Mosaic array.
*/
private List getUnresolvedMosaicArray(
TransferTransaction transaction) {
// Create Mosaics
final List unresolvedMosaicList =
new ArrayList<>(transaction.getMosaics().size());
//Sort mosaics first
final List sortedMosaics = transaction.getMosaics().stream()
.sorted(Comparator.comparing(m -> m.getId().getId()))
.collect(Collectors.toList());
for (final Mosaic mosaic : sortedMosaics) {
final UnresolvedMosaicBuilder mosaicBuilder =
UnresolvedMosaicBuilder.create(
new UnresolvedMosaicIdDto(mosaic.getId().getIdAsLong()),
new AmountDto(mosaic.getAmount().longValue()));
unresolvedMosaicList.add(mosaicBuilder);
}
return unresolvedMosaicList;
}
/**
* Gets message buffer.
*
* @return Message buffer.
*/
private ByteBuffer getMessageBuffer(TransferTransaction transaction) {
final byte byteMessageType = (byte) transaction.getMessage().getType().getValue();
final byte[] bytePayload = transaction.getMessage().getPayload()
.getBytes(StandardCharsets.UTF_8);
final ByteBuffer messageBuffer =
ByteBuffer.allocate(bytePayload.length + 1 /* for the message type */);
messageBuffer.put(byteMessageType);
messageBuffer.put(bytePayload);
return messageBuffer;
}
}
private static class MosaicSupplyChangeTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.MOSAIC_SUPPLY_CHANGE;
}
@Override
public Class getTransactionClass() {
return MosaicSupplyChangeTransaction.class;
}
@Override
public TransactionFactory> fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
MosaicSupplyChangeTransactionBodyBuilder builder = ((MosaicSupplyChangeTransactionBodyBuilder) transactionBuilder);
UnresolvedMosaicId mosaicId = SerializationUtils
.toUnresolvedMosaicId(builder.getMosaicId());
MosaicSupplyChangeActionType action = MosaicSupplyChangeActionType
.rawValueOf(builder.getAction().getValue());
BigInteger delta = SerializationUtils.toUnsignedBigInteger(builder.getDelta());
return MosaicSupplyChangeTransactionFactory
.create(networkType, mosaicId, action, delta);
}
@Override
public Serializer toBodyBuilder(MosaicSupplyChangeTransaction transaction) {
return MosaicSupplyChangeTransactionBodyBuilder.create(
new UnresolvedMosaicIdDto(transaction.getMosaicId().getId().longValue()),
new AmountDto(transaction.getDelta().longValue()),
MosaicSupplyChangeActionDto
.rawValueOf((byte) transaction.getAction().getValue()));
}
}
private static class MosaicDefinitionTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.MOSAIC_DEFINITION;
}
@Override
public Class getTransactionClass() {
return MosaicDefinitionTransaction.class;
}
@Override
public TransactionFactory> fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
MosaicDefinitionTransactionBodyBuilder builder = (MosaicDefinitionTransactionBodyBuilder) transactionBuilder;
MosaicNonce mosaicNonce = MosaicNonce
.createFromBigInteger((long) builder.getNonce().getMosaicNonce());
MosaicId mosaicId = SerializationUtils.toMosaicId(builder.getId());
MosaicFlags mosaicFlags = MosaicFlags
.create(builder.getFlags().contains(MosaicFlagsDto.SUPPLY_MUTABLE),
builder.getFlags().contains(MosaicFlagsDto.TRANSFERABLE),
builder.getFlags().contains(MosaicFlagsDto.RESTRICTABLE));
int divisibility = SerializationUtils.byteToUnsignedInt(builder.getDivisibility());
BlockDuration blockDuration = new BlockDuration(
builder.getDuration().getBlockDuration());
return MosaicDefinitionTransactionFactory
.create(networkType, mosaicNonce, mosaicId, mosaicFlags, divisibility,
blockDuration);
}
@Override
public Serializer toBodyBuilder(MosaicDefinitionTransaction transaction) {
return MosaicDefinitionTransactionBodyBuilder.create(
new MosaicIdDto(transaction.getMosaicId().getId().longValue()),
new BlockDurationDto(transaction.getBlockDuration().getDuration()),
new MosaicNonceDto(transaction.getMosaicNonce().getNonceAsInt()),
getMosaicFlagsEnumSet(transaction),
(byte) transaction.getDivisibility());
}
/**
* Get the mosaic flags.
*
* @return Mosaic flags
*/
private EnumSet getMosaicFlagsEnumSet(
MosaicDefinitionTransaction transaction) {
EnumSet mosaicFlagsBuilder = EnumSet.of(MosaicFlagsDto.NONE);
if (transaction.getMosaicFlags().isSupplyMutable()) {
mosaicFlagsBuilder.add(MosaicFlagsDto.SUPPLY_MUTABLE);
}
if (transaction.getMosaicFlags().isTransferable()) {
mosaicFlagsBuilder.add(MosaicFlagsDto.TRANSFERABLE);
}
if (transaction.getMosaicFlags().isRestrictable()) {
mosaicFlagsBuilder.add(MosaicFlagsDto.RESTRICTABLE);
}
return mosaicFlagsBuilder;
}
}
private static class AccountLinkTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.ACCOUNT_LINK;
}
@Override
public Class getTransactionClass() {
return AccountLinkTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
AccountLinkTransactionBodyBuilder builder = (AccountLinkTransactionBodyBuilder) transactionBuilder;
PublicAccount remoteAccount = SerializationUtils
.toPublicAccount(builder.getRemotePublicKey(), networkType);
AccountLinkAction linkAction = AccountLinkAction
.rawValueOf(builder.getLinkAction().getValue());
return AccountLinkTransactionFactory
.create(networkType, remoteAccount, linkAction);
}
@Override
public Serializer toBodyBuilder(AccountLinkTransaction transaction) {
return AccountLinkTransactionBodyBuilder.create(
SerializationUtils.toKeyDto(transaction.getRemoteAccount().getPublicKey()),
AccountLinkActionDto.rawValueOf(transaction.getLinkAction().getValue()))
;
}
}
private static class AccountMetadataTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.ACCOUNT_METADATA;
}
@Override
public Class getTransactionClass() {
return AccountMetadataTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
AccountMetadataTransactionBodyBuilder builder = (AccountMetadataTransactionBodyBuilder) transactionBuilder;
PublicAccount targetAccount = SerializationUtils
.toPublicAccount(builder.getTargetPublicKey(), networkType);
BigInteger scopedMetadataKey = SerializationUtils
.toUnsignedBigInteger(builder.getScopedMetadataKey());
String value = SerializationUtils.toString(builder.getValue());
return AccountMetadataTransactionFactory
.create(networkType, targetAccount, scopedMetadataKey, value)
.valueSizeDelta(SerializationUtils.shortToUnsignedInt(builder.getValueSizeDelta()));
}
@Override
public Serializer toBodyBuilder(AccountMetadataTransaction transaction) {
return AccountMetadataTransactionBodyBuilder.create(
SerializationUtils.toKeyDto(transaction.getTargetAccount().getPublicKey()),
transaction.getScopedMetadataKey().longValue(),
(short) transaction.getValueSizeDelta(),
ByteBuffer.wrap(MetadataTransaction.toByteArray(transaction.getValue()))
);
}
}
private static class MosaicMetadataTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.MOSAIC_METADATA;
}
@Override
public Class getTransactionClass() {
return MosaicMetadataTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
MosaicMetadataTransactionBodyBuilder builder = (MosaicMetadataTransactionBodyBuilder) transactionBuilder;
PublicAccount targetAccount = SerializationUtils
.toPublicAccount(builder.getTargetPublicKey(), networkType);
BigInteger scopedMetadataKey = SerializationUtils
.toUnsignedBigInteger(builder.getScopedMetadataKey());
String value = StringEncoder.getString(builder.getValue().array());
UnresolvedMosaicId targetMosaicId = SerializationUtils
.toUnresolvedMosaicId(builder.getTargetMosaicId());
return MosaicMetadataTransactionFactory
.create(networkType, targetAccount, targetMosaicId, scopedMetadataKey, value)
.valueSizeDelta(SerializationUtils.shortToUnsignedInt(builder.getValueSizeDelta()));
}
@Override
public Serializer toBodyBuilder(MosaicMetadataTransaction transaction) {
return MosaicMetadataTransactionBodyBuilder.create(
SerializationUtils.toKeyDto(transaction.getTargetAccount().getPublicKey()),
transaction.getScopedMetadataKey().longValue(),
new UnresolvedMosaicIdDto(transaction.getTargetMosaicId().getId().longValue()),
(short) transaction.getValueSizeDelta(),
ByteBuffer.wrap(MetadataTransaction.toByteArray(transaction.getValue()))
);
}
}
private static class NamespaceMetadataTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.NAMESPACE_METADATA;
}
@Override
public Class getTransactionClass() {
return NamespaceMetadataTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
NamespaceMetadataTransactionBodyBuilder builder = (NamespaceMetadataTransactionBodyBuilder) transactionBuilder;
PublicAccount targetAccount = SerializationUtils
.toPublicAccount(builder.getTargetPublicKey(), networkType);
BigInteger scopedMetadataKey = SerializationUtils
.toUnsignedBigInteger(builder.getScopedMetadataKey());
String value = StringEncoder.getString(builder.getValue().array());
NamespaceId targetNamespaceId = SerializationUtils
.toNamespaceId(builder.getTargetNamespaceId());
return NamespaceMetadataTransactionFactory
.create(networkType, targetAccount, targetNamespaceId, scopedMetadataKey, value)
.valueSizeDelta(SerializationUtils.shortToUnsignedInt(builder.getValueSizeDelta()));
}
@Override
public Serializer toBodyBuilder(NamespaceMetadataTransaction transaction) {
return NamespaceMetadataTransactionBodyBuilder.create(
new KeyDto(transaction.getTargetAccount().getPublicKey().getByteBuffer()),
transaction.getScopedMetadataKey().longValue(),
new NamespaceIdDto(transaction.getTargetNamespaceId().getId().longValue()),
(short) transaction.getValueSizeDelta(),
ByteBuffer.wrap(MetadataTransaction.toByteArray(transaction.getValue())
));
}
}
private static class NamespaceRegistrationTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.NAMESPACE_REGISTRATION;
}
@Override
public Class getTransactionClass() {
return NamespaceRegistrationTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
NamespaceRegistrationTransactionBodyBuilder builder = (NamespaceRegistrationTransactionBodyBuilder) transactionBuilder;
NamespaceRegistrationType namespaceRegistrationType = NamespaceRegistrationType
.rawValueOf(builder.getRegistrationType().getValue());
String namespaceName = StringEncoder.getString(builder.getName().array());
NamespaceId namespaceId = SerializationUtils
.toNamespaceId(builder.getId());
Optional duration =
namespaceRegistrationType == NamespaceRegistrationType.ROOT_NAMESPACE ? Optional
.ofNullable(builder.getDuration()).map(
BlockDurationDto::getBlockDuration)
.map(SerializationUtils::toUnsignedBigInteger)
: Optional.empty();
Optional parentId =
namespaceRegistrationType == NamespaceRegistrationType.SUB_NAMESPACE ? Optional
.of(builder.getParentId())
.map(SerializationUtils::toNamespaceId)
: Optional.empty();
return NamespaceRegistrationTransactionFactory
.create(networkType, namespaceName, namespaceId, namespaceRegistrationType,
duration, parentId);
}
@Override
public Serializer toBodyBuilder(NamespaceRegistrationTransaction transaction) {
NamespaceRegistrationTransactionBodyBuilder txBuilder;
ByteBuffer namespaceNameByteBuffer = ByteBuffer
.wrap(StringEncoder.getBytes(transaction.getNamespaceName()));
NamespaceIdDto namespaceIdDto = new NamespaceIdDto(
transaction.getNamespaceId().getId().longValue());
if (transaction.getNamespaceRegistrationType()
== NamespaceRegistrationType.ROOT_NAMESPACE) {
txBuilder =
NamespaceRegistrationTransactionBodyBuilder.create(
new BlockDurationDto(transaction.getDuration()
.orElseThrow(() -> new IllegalStateException("Duration is required"))
.longValue()),
namespaceIdDto,
namespaceNameByteBuffer);
} else {
txBuilder =
NamespaceRegistrationTransactionBodyBuilder.create(
new NamespaceIdDto(transaction.getParentId()
.orElseThrow(() -> new IllegalStateException("ParentId is required"))
.getId().longValue()),
namespaceIdDto,
namespaceNameByteBuffer);
}
return txBuilder;
}
}
private static class SecretLockTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.SECRET_LOCK;
}
@Override
public Class getTransactionClass() {
return SecretLockTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
SecretLockTransactionBodyBuilder builder = (SecretLockTransactionBodyBuilder) transactionBuilder;
Mosaic mosaic = SerializationUtils.toMosaic(builder.getMosaic());
BigInteger duration = SerializationUtils
.toUnsignedBigInteger(builder.getDuration().getBlockDuration());
LockHashAlgorithmType hashAlgorithm = LockHashAlgorithmType.rawValueOf(
SerializationUtils.byteToUnsignedInt(builder.getHashAlgorithm().getValue()));
String secret = SerializationUtils.toHexString(builder.getSecret());
UnresolvedAddress recipient = SerializationUtils
.toUnresolvedAddress(builder.getRecipientAddress());
return SecretLockTransactionFactory
.create(networkType, mosaic, duration, hashAlgorithm, secret, recipient);
}
@Override
public Serializer toBodyBuilder(SecretLockTransaction transaction) {
UnresolvedMosaicIdDto mosaicId = new UnresolvedMosaicIdDto(
transaction.getMosaic().getId().getIdAsLong());
AmountDto amount = new AmountDto(transaction.getMosaic().getAmount().longValue());
UnresolvedMosaicBuilder unresolvedMosaicBuilder = UnresolvedMosaicBuilder.create(
mosaicId,
amount);
return SecretLockTransactionBodyBuilder
.create(new Hash256Dto(getSecretBuffer(transaction)),
unresolvedMosaicBuilder,
new BlockDurationDto(transaction.getDuration().longValue()),
LockHashAlgorithmDto
.rawValueOf((byte) transaction.getHashAlgorithm().getValue()),
new UnresolvedAddressDto(
SerializationUtils
.fromUnresolvedAddressToByteBuffer(transaction.getRecipient(),
transaction.getNetworkType())))
;
}
/**
* Gets secret buffer.
*
* @param transaction the transaction.
* @return Secret buffer.
*/
private ByteBuffer getSecretBuffer(SecretLockTransaction transaction) {
final ByteBuffer secretBuffer = ByteBuffer.allocate(32);
secretBuffer.put(Hex.decode(transaction.getSecret()));
return secretBuffer;
}
}
private static class SecretProofTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.SECRET_PROOF;
}
@Override
public Class getTransactionClass() {
return SecretProofTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
SecretProofTransactionBodyBuilder builder = (SecretProofTransactionBodyBuilder) transactionBuilder;
LockHashAlgorithmType hashType = LockHashAlgorithmType.rawValueOf(
SerializationUtils.byteToUnsignedInt(builder.getHashAlgorithm().getValue()));
UnresolvedAddress recipient = SerializationUtils
.toUnresolvedAddress(builder.getRecipientAddress());
String secret = SerializationUtils.toHexString(builder.getSecret());
String proof = SerializationUtils.toHexString(builder.getProof());
return SecretProofTransactionFactory
.create(networkType, hashType, recipient, secret, proof);
}
@Override
public Serializer toBodyBuilder(SecretProofTransaction transaction) {
return SecretProofTransactionBodyBuilder.create(
new Hash256Dto(getSecretBuffer(transaction)),
LockHashAlgorithmDto.rawValueOf((byte) transaction.getHashType().getValue()),
new UnresolvedAddressDto(
SerializationUtils
.fromUnresolvedAddressToByteBuffer(transaction.getRecipient(),
transaction.getNetworkType())),
getProofBuffer(transaction));
}
/**
* Gets proof buffer
*
* @param transaction the transaction.
* @return the secret buffer.
*/
private ByteBuffer getSecretBuffer(SecretProofTransaction transaction) {
final ByteBuffer secretBuffer = ByteBuffer.allocate(32);
secretBuffer.put(Hex.decode(transaction.getSecret()));
return secretBuffer;
}
/**
* Gets proof buffer
*
* @param transaction the transaction.
* @return Proof buffer.
*/
private ByteBuffer getProofBuffer(SecretProofTransaction transaction) {
final byte[] proofBytes = Hex.decode(transaction.getProof());
return ByteBuffer.wrap(proofBytes);
}
}
private static class AddressAliasTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.ADDRESS_ALIAS;
}
@Override
public Class getTransactionClass() {
return AddressAliasTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
AddressAliasTransactionBodyBuilder builder = (AddressAliasTransactionBodyBuilder) transactionBuilder;
AliasAction aliasAction = AliasAction
.rawValueOf(builder.getAliasAction().getValue());
NamespaceId namespaceId = SerializationUtils
.toNamespaceId(builder.getNamespaceId());
Address address = SerializationUtils.toAddress(builder.getAddress());
return AddressAliasTransactionFactory
.create(networkType, aliasAction, namespaceId, address);
}
@Override
public Serializer toBodyBuilder(AddressAliasTransaction transaction) {
NamespaceIdDto namespaceIdDto = new NamespaceIdDto(
transaction.getNamespaceId().getIdAsLong());
AliasActionDto aliasActionDto = AliasActionDto
.rawValueOf(transaction.getAliasAction().getValue());
AddressDto addressDto = new AddressDto(SerializationUtils
.fromUnresolvedAddressToByteBuffer(transaction.getAddress(),
transaction.getNetworkType()));
return AddressAliasTransactionBodyBuilder
.create(namespaceIdDto, addressDto, aliasActionDto);
}
}
private static class MosaicAliasTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.MOSAIC_ALIAS;
}
@Override
public Class getTransactionClass() {
return MosaicAliasTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
MosaicAliasTransactionBodyBuilder builder = (MosaicAliasTransactionBodyBuilder) transactionBuilder;
AliasAction aliasAction = AliasAction
.rawValueOf(builder.getAliasAction().getValue());
NamespaceId namespaceId = SerializationUtils.toNamespaceId(builder.getNamespaceId());
MosaicId mosaicId = SerializationUtils.toMosaicId(builder.getMosaicId());
return MosaicAliasTransactionFactory
.create(networkType, aliasAction, namespaceId, mosaicId);
}
@Override
public Serializer toBodyBuilder(MosaicAliasTransaction transaction) {
return MosaicAliasTransactionBodyBuilder.create(
new NamespaceIdDto(transaction.getNamespaceId().getIdAsLong()),
new MosaicIdDto(transaction.getMosaicId().getIdAsLong()),
AliasActionDto.rawValueOf(transaction.getAliasAction().getValue())
);
}
}
private static class HashLockTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.HASH_LOCK;
}
@Override
public Class getTransactionClass() {
return HashLockTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
HashLockTransactionBodyBuilder builder = (HashLockTransactionBodyBuilder) transactionBuilder;
Mosaic mosaic = SerializationUtils.toMosaic(builder.getMosaic());
BigInteger duration = SerializationUtils
.toUnsignedBigInteger(builder.getDuration().getBlockDuration());
return HashLockTransactionFactory
.create(networkType, mosaic, duration,
SerializationUtils.toHexString(builder.getHash()));
}
@Override
public Serializer toBodyBuilder(HashLockTransaction transaction) {
return HashLockTransactionBodyBuilder.create(
UnresolvedMosaicBuilder.create(
new UnresolvedMosaicIdDto(transaction.getMosaic().getId().getIdAsLong()),
new AmountDto(transaction.getMosaic().getAmount().longValue())),
new BlockDurationDto(transaction.getDuration().longValue()),
new Hash256Dto(getHashBuffer(transaction)));
}
/**
* Gets hash buffer.
*
* @param transaction the transaction.
* @return Hash buffer.
*/
private ByteBuffer getHashBuffer(HashLockTransaction transaction) {
return ByteBuffer.wrap(Hex.decode(transaction.getHash()));
}
}
private static class AccountAddressRestrictionTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.ACCOUNT_ADDRESS_RESTRICTION;
}
@Override
public Class getTransactionClass() {
return AccountAddressRestrictionTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
AccountAddressRestrictionTransactionBodyBuilder builder = (AccountAddressRestrictionTransactionBodyBuilder) transactionBuilder;
long restrictionFlagsValue = builder.getRestrictionFlags().stream()
.mapToLong(AccountRestrictionFlagsDto::getValue).sum();
AccountRestrictionFlags restrictionFlags = AccountRestrictionFlags
.rawValueOf((int) restrictionFlagsValue);
List restrictionAdditions = builder.getRestrictionAdditions()
.stream()
.map(SerializationUtils::toUnresolvedAddress)
.collect(Collectors.toList());
List restrictionDeletions = builder.getRestrictionDeletions()
.stream()
.map(SerializationUtils::toUnresolvedAddress)
.collect(Collectors.toList());
return AccountAddressRestrictionTransactionFactory
.create(networkType, restrictionFlags, restrictionAdditions, restrictionDeletions);
}
@Override
public Serializer toBodyBuilder(AccountAddressRestrictionTransaction transaction) {
EnumSet flags = transaction.getRestrictionFlags().getFlags()
.stream().map(f -> AccountRestrictionFlagsDto.rawValueOf(
(short) f.getValue())).collect(Collectors
.toCollection(() -> EnumSet.noneOf(AccountRestrictionFlagsDto.class)));
List restrictionAdditions = transaction.getRestrictionAdditions()
.stream()
.map(
a -> SerializationUtils.toUnresolvedAddress(a, transaction.getNetworkType()))
.collect(Collectors.toList());
List restrictionDeletions = transaction.getRestrictionDeletions()
.stream()
.map(
a -> SerializationUtils.toUnresolvedAddress(a, transaction.getNetworkType()))
.collect(Collectors.toList());
return AccountAddressRestrictionTransactionBodyBuilder.create(
flags,
restrictionAdditions, restrictionDeletions);
}
}
private static class AccountMosaicRestrictionTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.ACCOUNT_MOSAIC_RESTRICTION;
}
@Override
public Class getTransactionClass() {
return AccountMosaicRestrictionTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
AccountMosaicRestrictionTransactionBodyBuilder builder = (AccountMosaicRestrictionTransactionBodyBuilder) transactionBuilder;
long restrictionFlagsValues = builder.getRestrictionFlags().stream()
.mapToLong(AccountRestrictionFlagsDto::getValue).sum();
AccountRestrictionFlags restrictionFlags = AccountRestrictionFlags
.rawValueOf((int) restrictionFlagsValues);
List restrictionAdditions = builder.getRestrictionAdditions()
.stream().map(SerializationUtils::toUnresolvedMosaicId)
.collect(Collectors.toList());
List restrictionDeletions = builder.getRestrictionDeletions()
.stream().map(SerializationUtils::toUnresolvedMosaicId)
.collect(Collectors.toList());
return AccountMosaicRestrictionTransactionFactory
.create(networkType, restrictionFlags, restrictionAdditions, restrictionDeletions);
}
@Override
public Serializer toBodyBuilder(AccountMosaicRestrictionTransaction transaction) {
EnumSet flags = transaction.getRestrictionFlags().getFlags()
.stream().map(f -> AccountRestrictionFlagsDto.rawValueOf(
(short) f.getValue())).collect(Collectors
.toCollection(() -> EnumSet.noneOf(AccountRestrictionFlagsDto.class)));
List restrictionAdditions = transaction.getRestrictionAdditions()
.stream().map(a -> new UnresolvedMosaicIdDto(a.getIdAsLong()))
.collect(Collectors.toList());
List restrictionDeletions = transaction.getRestrictionDeletions()
.stream().map(a -> new UnresolvedMosaicIdDto(a.getIdAsLong()))
.collect(Collectors.toList());
return AccountMosaicRestrictionTransactionBodyBuilder.create(
flags,
restrictionAdditions, restrictionDeletions);
}
}
private static class AccountOperationRestrictionTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.ACCOUNT_OPERATION_RESTRICTION;
}
@Override
public Class getTransactionClass() {
return AccountOperationRestrictionTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
AccountOperationRestrictionTransactionBodyBuilder builder = (AccountOperationRestrictionTransactionBodyBuilder) transactionBuilder;
long restrictionFlagsValue = builder.getRestrictionFlags().stream()
.mapToLong(AccountRestrictionFlagsDto::getValue).sum();
AccountRestrictionFlags restrictionFlags = AccountRestrictionFlags
.rawValueOf((int) restrictionFlagsValue);
List restrictionAdditions = builder.getRestrictionAdditions()
.stream()
.map(op -> TransactionType.rawValueOf(op.getValue()))
.collect(Collectors.toList());
List restrictionDeletions = builder.getRestrictionDeletions()
.stream()
.map(op -> TransactionType.rawValueOf(op.getValue()))
.collect(Collectors.toList());
return AccountOperationRestrictionTransactionFactory
.create(networkType, restrictionFlags, restrictionAdditions, restrictionDeletions);
}
@Override
public Serializer toBodyBuilder(AccountOperationRestrictionTransaction transaction) {
EnumSet flags = transaction.getRestrictionFlags().getFlags()
.stream().map(f -> AccountRestrictionFlagsDto.rawValueOf(
(short) f.getValue())).collect(Collectors
.toCollection(() -> EnumSet.noneOf(AccountRestrictionFlagsDto.class)));
List restrictionAdditions = transaction.getRestrictionAdditions()
.stream()
.map(
a -> EntityTypeDto.rawValueOf((short) a.getValue()))
.collect(Collectors.toList());
List restrictionDeletions = transaction.getRestrictionDeletions()
.stream()
.map(
a -> EntityTypeDto.rawValueOf((short) a.getValue()))
.collect(Collectors.toList());
return AccountOperationRestrictionTransactionBodyBuilder.create(
flags,
restrictionAdditions, restrictionDeletions);
}
}
private static class MosaicAddressRestrictionTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.MOSAIC_ADDRESS_RESTRICTION;
}
@Override
public Class getTransactionClass() {
return MosaicAddressRestrictionTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
MosaicAddressRestrictionTransactionBodyBuilder builder = (MosaicAddressRestrictionTransactionBodyBuilder) transactionBuilder;
UnresolvedMosaicId mosaicId = SerializationUtils
.toUnresolvedMosaicId(builder.getMosaicId());
BigInteger restrictionKey = SerializationUtils
.toUnsignedBigInteger(builder.getRestrictionKey());
UnresolvedAddress targetAddress = SerializationUtils
.toUnresolvedAddress(builder.getTargetAddress());
BigInteger newRestrictionValue = SerializationUtils
.toUnsignedBigInteger(builder.getNewRestrictionValue());
BigInteger previousRestrictionValue = SerializationUtils
.toUnsignedBigInteger(builder.getPreviousRestrictionValue());
return MosaicAddressRestrictionTransactionFactory
.create(networkType, mosaicId, restrictionKey, targetAddress, newRestrictionValue)
.previousRestrictionValue(previousRestrictionValue);
}
@Override
public Serializer toBodyBuilder(MosaicAddressRestrictionTransaction transaction) {
UnresolvedAddressDto unresolvedAddressDto = SerializationUtils
.toUnresolvedAddress(transaction.getTargetAddress(),
transaction.getNetworkType());
return MosaicAddressRestrictionTransactionBodyBuilder.create(
new UnresolvedMosaicIdDto(transaction.getMosaicId().getIdAsLong()),
transaction.getRestrictionKey().longValue(),
transaction.getPreviousRestrictionValue().longValue(),
transaction.getNewRestrictionValue().longValue(), unresolvedAddressDto
);
}
}
private static class MosaicGlobalRestrictionTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.MOSAIC_GLOBAL_RESTRICTION;
}
@Override
public Class getTransactionClass() {
return MosaicGlobalRestrictionTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
MosaicGlobalRestrictionTransactionBodyBuilder builder = (MosaicGlobalRestrictionTransactionBodyBuilder) transactionBuilder;
UnresolvedMosaicId mosaicId = SerializationUtils
.toUnresolvedMosaicId(builder.getMosaicId());
BigInteger restrictionKey = SerializationUtils
.toUnsignedBigInteger(builder.getRestrictionKey());
BigInteger newRestrictionValue = SerializationUtils
.toUnsignedBigInteger(builder.getNewRestrictionValue());
BigInteger previousRestrictionValue = SerializationUtils
.toUnsignedBigInteger(builder.getPreviousRestrictionValue());
MosaicRestrictionType newRestrictionType = MosaicRestrictionType
.rawValueOf(builder.getNewRestrictionType().getValue());
MosaicRestrictionType previousRestrictionType = MosaicRestrictionType
.rawValueOf(builder.getPreviousRestrictionType().getValue());
return MosaicGlobalRestrictionTransactionFactory
.create(networkType, mosaicId, restrictionKey, newRestrictionValue,
newRestrictionType)
.referenceMosaicId(
SerializationUtils.toUnresolvedMosaicId(builder.getReferenceMosaicId()))
.previousRestrictionValue(previousRestrictionValue)
.previousRestrictionType(previousRestrictionType);
}
@Override
public Serializer toBodyBuilder(MosaicGlobalRestrictionTransaction transaction) {
return MosaicGlobalRestrictionTransactionBodyBuilder.create(
new UnresolvedMosaicIdDto(transaction.getMosaicId().getIdAsLong()),
new UnresolvedMosaicIdDto(transaction.getReferenceMosaicId().getIdAsLong()),
transaction.getRestrictionKey().longValue(),
transaction.getPreviousRestrictionValue().longValue(),
transaction.getNewRestrictionValue().longValue(),
MosaicRestrictionTypeDto
.rawValueOf(transaction.getPreviousRestrictionType().getValue()),
MosaicRestrictionTypeDto
.rawValueOf(transaction.getNewRestrictionType().getValue()));
}
}
private static class MultisigAccountModificationTransactionSerializer implements
TransactionSerializer {
@Override
public TransactionType getTransactionType() {
return TransactionType.MULTISIG_ACCOUNT_MODIFICATION;
}
@Override
public Class getTransactionClass() {
return MultisigAccountModificationTransaction.class;
}
@Override
public TransactionFactory fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
MultisigAccountModificationTransactionBodyBuilder builder = (MultisigAccountModificationTransactionBodyBuilder) transactionBuilder;
byte minApprovalDelta = builder.getMinApprovalDelta();
byte minRemovalDelta = builder.getMinRemovalDelta();
List publicKeyAdditions = builder.getPublicKeyAdditions()
.stream()
.map(op -> SerializationUtils.toPublicAccount(op, networkType))
.collect(Collectors.toList());
List publicKeyDeletions = builder.getPublicKeyDeletions()
.stream()
.map(op -> SerializationUtils.toPublicAccount(op, networkType))
.collect(Collectors.toList());
return MultisigAccountModificationTransactionFactory
.create(networkType, minApprovalDelta, minRemovalDelta, publicKeyAdditions,
publicKeyDeletions);
}
@Override
public Serializer toBodyBuilder(MultisigAccountModificationTransaction transaction) {
List publicKeyAdditions = transaction.getPublicKeyAdditions()
.stream()
.map(
a -> SerializationUtils.toKeyDto(a.getPublicKey()))
.collect(Collectors.toList());
List publicKeyDeletions = transaction.getPublicKeyDeletions()
.stream()
.map(
a -> SerializationUtils.toKeyDto(a.getPublicKey()))
.collect(Collectors.toList());
return MultisigAccountModificationTransactionBodyBuilder.create(
transaction.getMinRemovalDelta(),
transaction.getMinApprovalDelta(),
publicKeyAdditions, publicKeyDeletions);
}
}
private static class AggregateTransactionSerializer implements
TransactionSerializer {
private final TransactionType transactionType;
private final BinarySerializationImpl transactionSerialization;
public AggregateTransactionSerializer(TransactionType transactionType,
BinarySerializationImpl transactionSerialization) {
this.transactionType = transactionType;
this.transactionSerialization = transactionSerialization;
}
@Override
public TransactionType getTransactionType() {
return transactionType;
}
@Override
public Class getTransactionClass() {
return AggregateTransaction.class;
}
@Override
public TransactionFactory> fromBodyBuilder(NetworkType networkType,
Serializer transactionBuilder) {
AggregateTransactionBodyBuilder builder = (AggregateTransactionBodyBuilder) transactionBuilder;
List transactions = builder.getTransactions().stream()
.map(transactionSerialization::toTransaction
).collect(Collectors.toList());
List cosignatures = builder.getCosignatures().stream()
.map(cosignatureBuilder -> getAggregateTransactionCosignature(networkType,
cosignatureBuilder)).collect(Collectors.toList());
return AggregateTransactionFactory.create(
getTransactionType(), networkType,
SerializationUtils.toHexString(builder.getTransactionsHash()), transactions,
cosignatures);
}
private AggregateTransactionCosignature getAggregateTransactionCosignature(
NetworkType networkType, CosignatureBuilder cosignatureBuilder) {
PublicAccount signer =
SerializationUtils.toPublicAccount(
cosignatureBuilder.getSignerPublicKey(), networkType);
String cosignature = SerializationUtils
.toHexString(cosignatureBuilder.getSignature().getSignature());
return new AggregateTransactionCosignature(cosignature, signer);
}
@Override
public Serializer toBodyBuilder(AggregateTransaction transaction) {
List transactions = transaction.getInnerTransactions()
.stream()
.map(transactionSerialization::toEmbeddedTransactionBuilder
).collect(Collectors.toList());
List cosignatures = transaction.getCosignatures().stream()
.map(this::getCosignatureBuilder).collect(Collectors.toList());
return AggregateTransactionBodyBuilder
.create(SerializationUtils.toHash256Dto(transaction.getTransactionsHash()),
transactions, cosignatures);
}
private CosignatureBuilder getCosignatureBuilder(AggregateTransactionCosignature c) {
return CosignatureBuilder
.create(SerializationUtils.toKeyDto(c.getSigner().getPublicKey()),
SerializationUtils.toSignatureDto(c.getSignature()));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy