forked from Qortal/qortal
Merge branch 'message-wo-recipient' into launch
This commit is contained in:
commit
a7b9215ace
@ -815,9 +815,10 @@ public class CrossChainResource {
|
||||
|
||||
Long fee = null;
|
||||
long amount = 0L;
|
||||
Long assetId = null; // no assetId as amount is zero
|
||||
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(txTimestamp, Group.NO_GROUP, lastReference, senderPublicKey, fee, null);
|
||||
TransactionData messageTransactionData = new MessageTransactionData(baseTransactionData, 4, atAddress, Asset.QORT, amount, messageData, false, false);
|
||||
TransactionData messageTransactionData = new MessageTransactionData(baseTransactionData, 4, atAddress, amount, assetId, messageData, false, false);
|
||||
|
||||
MessageTransaction messageTransaction = new MessageTransaction(repository, messageTransactionData);
|
||||
|
||||
|
@ -5,7 +5,6 @@ import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import org.qortal.asset.Asset;
|
||||
import org.qortal.transaction.Transaction.TransactionType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
@ -16,14 +15,24 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
public class MessageTransactionData extends TransactionData {
|
||||
|
||||
// Properties
|
||||
|
||||
private byte[] senderPublicKey;
|
||||
|
||||
private int version;
|
||||
|
||||
// Not always present
|
||||
private String recipient;
|
||||
private Long assetId;
|
||||
|
||||
@XmlJavaTypeAdapter(value = org.qortal.api.AmountTypeAdapter.class)
|
||||
private long amount;
|
||||
|
||||
// Not present if amount is zero
|
||||
private Long assetId;
|
||||
|
||||
private byte[] data;
|
||||
|
||||
private boolean isText;
|
||||
|
||||
private boolean isEncrypted;
|
||||
|
||||
// Constructors
|
||||
@ -38,19 +47,14 @@ public class MessageTransactionData extends TransactionData {
|
||||
}
|
||||
|
||||
public MessageTransactionData(BaseTransactionData baseTransactionData,
|
||||
int version, String recipient, Long assetId, long amount, byte[] data, boolean isText, boolean isEncrypted) {
|
||||
int version, String recipient, long amount, Long assetId, byte[] data, boolean isText, boolean isEncrypted) {
|
||||
super(TransactionType.MESSAGE, baseTransactionData);
|
||||
|
||||
this.senderPublicKey = baseTransactionData.creatorPublicKey;
|
||||
this.version = version;
|
||||
this.recipient = recipient;
|
||||
|
||||
if (assetId != null)
|
||||
this.assetId = assetId;
|
||||
else
|
||||
this.assetId = Asset.QORT;
|
||||
|
||||
this.amount = amount;
|
||||
this.assetId = assetId;
|
||||
this.data = data;
|
||||
this.isText = isText;
|
||||
this.isEncrypted = isEncrypted;
|
||||
@ -70,23 +74,23 @@ public class MessageTransactionData extends TransactionData {
|
||||
return this.recipient;
|
||||
}
|
||||
|
||||
public Long getAssetId() {
|
||||
return this.assetId;
|
||||
}
|
||||
|
||||
public long getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public Long getAssetId() {
|
||||
return this.assetId;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public boolean getIsText() {
|
||||
public boolean isText() {
|
||||
return this.isText;
|
||||
}
|
||||
|
||||
public boolean getIsEncrypted() {
|
||||
public boolean isEncrypted() {
|
||||
return this.isEncrypted;
|
||||
}
|
||||
|
||||
|
@ -269,8 +269,8 @@ public class HSQLDBDatabaseUpdates {
|
||||
case 6:
|
||||
// Message Transactions
|
||||
stmt.execute("CREATE TABLE MessageTransactions (signature Signature, version TINYINT NOT NULL, "
|
||||
+ "sender QortalPublicKey NOT NULL, recipient QortalAddress NOT NULL, "
|
||||
+ "is_text BOOLEAN NOT NULL, is_encrypted BOOLEAN NOT NULL, amount QortalAmount NOT NULL, asset_id AssetID NOT NULL, data MessageData NOT NULL, "
|
||||
+ "sender QortalPublicKey NOT NULL, recipient QortalAddress, amount QortalAmount NOT NULL, asset_id AssetID, "
|
||||
+ "is_text BOOLEAN NOT NULL, is_encrypted BOOLEAN NOT NULL, data MessageData NOT NULL, "
|
||||
+ TRANSACTION_KEYS + ")");
|
||||
break;
|
||||
|
||||
|
@ -36,7 +36,7 @@ public class HSQLDBMessageTransactionRepository extends HSQLDBTransactionReposit
|
||||
|
||||
byte[] data = resultSet.getBytes(7);
|
||||
|
||||
return new MessageTransactionData(baseTransactionData, version, recipient, assetId, amount, data, isText, isEncrypted);
|
||||
return new MessageTransactionData(baseTransactionData, version, recipient, amount, assetId, data, isText, isEncrypted);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch message transaction from repository", e);
|
||||
}
|
||||
@ -50,7 +50,7 @@ public class HSQLDBMessageTransactionRepository extends HSQLDBTransactionReposit
|
||||
|
||||
saveHelper.bind("signature", messageTransactionData.getSignature()).bind("version", messageTransactionData.getVersion())
|
||||
.bind("sender", messageTransactionData.getSenderPublicKey()).bind("recipient", messageTransactionData.getRecipient())
|
||||
.bind("is_text", messageTransactionData.getIsText()).bind("is_encrypted", messageTransactionData.getIsEncrypted())
|
||||
.bind("is_text", messageTransactionData.isText()).bind("is_encrypted", messageTransactionData.isEncrypted())
|
||||
.bind("amount", messageTransactionData.getAmount()).bind("asset_id", messageTransactionData.getAssetId())
|
||||
.bind("data", messageTransactionData.getData());
|
||||
|
||||
|
@ -4,6 +4,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.qortal.account.Account;
|
||||
import org.qortal.asset.Asset;
|
||||
import org.qortal.data.PaymentData;
|
||||
import org.qortal.data.transaction.MessageTransactionData;
|
||||
import org.qortal.data.transaction.TransactionData;
|
||||
@ -13,14 +14,17 @@ import org.qortal.repository.Repository;
|
||||
|
||||
public class MessageTransaction extends Transaction {
|
||||
|
||||
// Useful constants
|
||||
|
||||
public static final int MAX_DATA_SIZE = 4000;
|
||||
|
||||
// Properties
|
||||
|
||||
private MessageTransactionData messageTransactionData;
|
||||
|
||||
/** Cached, lazy-instantiated payment data. Use {@link #getPaymentData()} instead! */
|
||||
private PaymentData paymentData = null;
|
||||
|
||||
// Other useful constants
|
||||
public static final int MAX_DATA_SIZE = 4000;
|
||||
private static final boolean isZeroAmountValid = true;
|
||||
|
||||
// Constructors
|
||||
|
||||
@ -34,6 +38,9 @@ public class MessageTransaction extends Transaction {
|
||||
|
||||
@Override
|
||||
public List<String> getRecipientAddresses() throws DataException {
|
||||
if (this.messageTransactionData.getRecipient() == null)
|
||||
return Collections.emptyList();
|
||||
|
||||
return Collections.singletonList(this.messageTransactionData.getRecipient());
|
||||
}
|
||||
|
||||
@ -62,42 +69,80 @@ public class MessageTransaction extends Transaction {
|
||||
if (this.messageTransactionData.getData().length < 1 || this.messageTransactionData.getData().length > MAX_DATA_SIZE)
|
||||
return ValidationResult.INVALID_DATA_LENGTH;
|
||||
|
||||
// If message has no recipient then it cannot have a payment
|
||||
if (this.messageTransactionData.getRecipient() == null && this.messageTransactionData.getAmount() != 0)
|
||||
return ValidationResult.INVALID_AMOUNT;
|
||||
|
||||
// If message has no payment then we only need to do a simple balance check for fee
|
||||
if (this.messageTransactionData.getAmount() == 0) {
|
||||
if (getSender().getConfirmedBalance(Asset.QORT) < this.messageTransactionData.getFee())
|
||||
return ValidationResult.NO_BALANCE;
|
||||
|
||||
return ValidationResult.OK;
|
||||
}
|
||||
|
||||
// Wrap and delegate final payment checks to Payment class
|
||||
return new Payment(this.repository).isValid(this.messageTransactionData.getSenderPublicKey(), getPaymentData(), this.messageTransactionData.getFee(),
|
||||
isZeroAmountValid);
|
||||
return new Payment(this.repository).isValid(this.messageTransactionData.getSenderPublicKey(), getPaymentData(),
|
||||
this.messageTransactionData.getFee(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResult isProcessable() throws DataException {
|
||||
// If we have no amount then we can always process
|
||||
if (this.messageTransactionData.getAmount() == 0L)
|
||||
return ValidationResult.OK;
|
||||
|
||||
// Wrap and delegate final processable checks to Payment class
|
||||
return new Payment(this.repository).isProcessable(this.messageTransactionData.getSenderPublicKey(), getPaymentData(), this.messageTransactionData.getFee(),
|
||||
isZeroAmountValid);
|
||||
return new Payment(this.repository).isProcessable(this.messageTransactionData.getSenderPublicKey(),
|
||||
getPaymentData(), this.messageTransactionData.getFee(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process() throws DataException {
|
||||
// If we have no amount then there's nothing to do
|
||||
if (this.messageTransactionData.getAmount() == 0L)
|
||||
return;
|
||||
|
||||
// Wrap and delegate payment processing to Payment class.
|
||||
new Payment(this.repository).process(this.messageTransactionData.getSenderPublicKey(), getPaymentData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processReferencesAndFees() throws DataException {
|
||||
// If we have no amount then we only need to process sender's reference and fees
|
||||
if (this.messageTransactionData.getAmount() == 0L) {
|
||||
super.processReferencesAndFees();
|
||||
return;
|
||||
}
|
||||
|
||||
// Wrap and delegate references processing to Payment class. Only update recipient's last reference if transferring QORT.
|
||||
new Payment(this.repository).processReferencesAndFees(this.messageTransactionData.getSenderPublicKey(), getPaymentData(), this.messageTransactionData.getFee(),
|
||||
this.messageTransactionData.getSignature(), false);
|
||||
new Payment(this.repository).processReferencesAndFees(this.messageTransactionData.getSenderPublicKey(),
|
||||
getPaymentData(), this.messageTransactionData.getFee(), this.messageTransactionData.getSignature(),
|
||||
false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void orphan() throws DataException {
|
||||
// If we have no amount then there's nothing to do
|
||||
if (this.messageTransactionData.getAmount() == 0L)
|
||||
return;
|
||||
|
||||
// Wrap and delegate payment processing to Payment class.
|
||||
new Payment(this.repository).orphan(this.messageTransactionData.getSenderPublicKey(), getPaymentData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void orphanReferencesAndFees() throws DataException {
|
||||
// If we have no amount then we only need to orphan sender's reference and fees
|
||||
if (this.messageTransactionData.getAmount() == 0L) {
|
||||
super.orphanReferencesAndFees();
|
||||
return;
|
||||
}
|
||||
|
||||
// Wrap and delegate references processing to Payment class. Only revert recipient's last reference if transferring QORT.
|
||||
new Payment(this.repository).orphanReferencesAndFees(this.messageTransactionData.getSenderPublicKey(), getPaymentData(), this.messageTransactionData.getFee(),
|
||||
this.messageTransactionData.getSignature(), this.messageTransactionData.getReference(), false);
|
||||
new Payment(this.repository).orphanReferencesAndFees(this.messageTransactionData.getSenderPublicKey(),
|
||||
getPaymentData(), this.messageTransactionData.getFee(), this.messageTransactionData.getSignature(),
|
||||
this.messageTransactionData.getReference(), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,12 +19,13 @@ import com.google.common.primitives.Longs;
|
||||
public class MessageTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
// Property lengths
|
||||
private static final int HAS_RECIPIENT_LENGTH = BOOLEAN_LENGTH;
|
||||
private static final int RECIPIENT_LENGTH = ADDRESS_LENGTH;
|
||||
private static final int DATA_SIZE_LENGTH = INT_LENGTH;
|
||||
private static final int IS_TEXT_LENGTH = BOOLEAN_LENGTH;
|
||||
private static final int IS_ENCRYPTED_LENGTH = BOOLEAN_LENGTH;
|
||||
|
||||
private static final int EXTRAS_LENGTH = RECIPIENT_LENGTH + ASSET_ID_LENGTH + AMOUNT_LENGTH + DATA_SIZE_LENGTH + IS_ENCRYPTED_LENGTH + IS_TEXT_LENGTH;
|
||||
private static final int EXTRAS_LENGTH = HAS_RECIPIENT_LENGTH + AMOUNT_LENGTH + DATA_SIZE_LENGTH + IS_ENCRYPTED_LENGTH + IS_TEXT_LENGTH;
|
||||
|
||||
protected static final TransactionLayout layout;
|
||||
|
||||
@ -35,9 +36,10 @@ public class MessageTransactionTransformer extends TransactionTransformer {
|
||||
layout.add("transaction's groupID", TransformationType.INT);
|
||||
layout.add("reference", TransformationType.SIGNATURE);
|
||||
layout.add("sender's public key", TransformationType.PUBLIC_KEY);
|
||||
layout.add("recipient", TransformationType.ADDRESS);
|
||||
layout.add("asset ID of payment", TransformationType.LONG);
|
||||
layout.add("has recipient?", TransformationType.BOOLEAN);
|
||||
layout.add("? recipient", TransformationType.ADDRESS);
|
||||
layout.add("payment (can be zero)", TransformationType.AMOUNT);
|
||||
layout.add("asset ID of payment (if payment not zero)", TransformationType.LONG);
|
||||
layout.add("message length", TransformationType.INT);
|
||||
layout.add("message", TransformationType.DATA);
|
||||
layout.add("is message encrypted?", TransformationType.BOOLEAN);
|
||||
@ -58,12 +60,13 @@ public class MessageTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
byte[] senderPublicKey = Serialization.deserializePublicKey(byteBuffer);
|
||||
|
||||
String recipient = Serialization.deserializeAddress(byteBuffer);
|
||||
|
||||
long assetId = byteBuffer.getLong();
|
||||
boolean hasRecipient = byteBuffer.get() != 0;
|
||||
String recipient = hasRecipient ? Serialization.deserializeAddress(byteBuffer) : null;
|
||||
|
||||
long amount = byteBuffer.getLong();
|
||||
|
||||
Long assetId = amount != 0 ? byteBuffer.getLong() : null;
|
||||
|
||||
int dataSize = byteBuffer.getInt();
|
||||
// Don't allow invalid dataSize here to avoid run-time issues
|
||||
if (dataSize > MessageTransaction.MAX_DATA_SIZE)
|
||||
@ -83,13 +86,21 @@ public class MessageTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, senderPublicKey, fee, signature);
|
||||
|
||||
return new MessageTransactionData(baseTransactionData, version, recipient, assetId, amount, data, isText, isEncrypted);
|
||||
return new MessageTransactionData(baseTransactionData, version, recipient, amount, assetId, data, isText, isEncrypted);
|
||||
}
|
||||
|
||||
public static int getDataLength(TransactionData transactionData) throws TransformationException {
|
||||
MessageTransactionData messageTransactionData = (MessageTransactionData) transactionData;
|
||||
|
||||
return getBaseLength(transactionData) + EXTRAS_LENGTH + messageTransactionData.getData().length;
|
||||
int dataLength = getBaseLength(transactionData) + EXTRAS_LENGTH + messageTransactionData.getData().length;
|
||||
|
||||
if (messageTransactionData.getRecipient() != null)
|
||||
dataLength += RECIPIENT_LENGTH;
|
||||
|
||||
if (messageTransactionData.getAmount() != 0)
|
||||
dataLength += ASSET_ID_LENGTH;
|
||||
|
||||
return dataLength;
|
||||
}
|
||||
|
||||
public static byte[] toBytes(TransactionData transactionData) throws TransformationException {
|
||||
@ -100,19 +111,25 @@ public class MessageTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
transformCommonBytes(transactionData, bytes);
|
||||
|
||||
Serialization.serializeAddress(bytes, messageTransactionData.getRecipient());
|
||||
|
||||
bytes.write(Longs.toByteArray(messageTransactionData.getAssetId()));
|
||||
if (messageTransactionData.getRecipient() != null) {
|
||||
bytes.write((byte) 1);
|
||||
Serialization.serializeAddress(bytes, messageTransactionData.getRecipient());
|
||||
} else {
|
||||
bytes.write((byte) 0);
|
||||
}
|
||||
|
||||
bytes.write(Longs.toByteArray(messageTransactionData.getAmount()));
|
||||
|
||||
if (messageTransactionData.getAmount() != 0)
|
||||
bytes.write(Longs.toByteArray(messageTransactionData.getAssetId()));
|
||||
|
||||
bytes.write(Ints.toByteArray(messageTransactionData.getData().length));
|
||||
|
||||
bytes.write(messageTransactionData.getData());
|
||||
|
||||
bytes.write((byte) (messageTransactionData.getIsEncrypted() ? 1 : 0));
|
||||
bytes.write((byte) (messageTransactionData.isEncrypted() ? 1 : 0));
|
||||
|
||||
bytes.write((byte) (messageTransactionData.getIsText() ? 1 : 0));
|
||||
bytes.write((byte) (messageTransactionData.isText() ? 1 : 0));
|
||||
|
||||
bytes.write(Longs.toByteArray(messageTransactionData.getFee()));
|
||||
|
||||
|
154
src/test/java/org/qortal/test/MessageTests.java
Normal file
154
src/test/java/org/qortal/test/MessageTests.java
Normal file
@ -0,0 +1,154 @@
|
||||
package org.qortal.test;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.qortal.asset.Asset;
|
||||
import org.qortal.data.transaction.MessageTransactionData;
|
||||
import org.qortal.data.transaction.TransactionData;
|
||||
import org.qortal.group.Group;
|
||||
import org.qortal.group.Group.ApprovalThreshold;
|
||||
import org.qortal.repository.DataException;
|
||||
import org.qortal.repository.Repository;
|
||||
import org.qortal.repository.RepositoryManager;
|
||||
import org.qortal.test.common.BlockUtils;
|
||||
import org.qortal.test.common.Common;
|
||||
import org.qortal.test.common.GroupUtils;
|
||||
import org.qortal.test.common.TestAccount;
|
||||
import org.qortal.test.common.TransactionUtils;
|
||||
import org.qortal.test.common.transaction.TestTransaction;
|
||||
import org.qortal.transaction.MessageTransaction;
|
||||
import org.qortal.transaction.Transaction;
|
||||
import org.qortal.transaction.Transaction.TransactionType;
|
||||
import org.qortal.transaction.Transaction.ValidationResult;
|
||||
import org.qortal.transform.TransformationException;
|
||||
import org.qortal.transform.transaction.MessageTransactionTransformer;
|
||||
import org.qortal.transform.transaction.TransactionTransformer;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class MessageTests extends Common {
|
||||
|
||||
private static final int version = 3;
|
||||
private static final String recipient = Common.getTestAccount(null, "bob").getAddress();
|
||||
|
||||
|
||||
@Before
|
||||
public void beforeTest() throws DataException {
|
||||
Common.useDefaultSettings();
|
||||
}
|
||||
|
||||
@After
|
||||
public void afterTest() throws DataException {
|
||||
Common.orphanCheck();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validityTests() throws DataException {
|
||||
// with recipient, with amount
|
||||
assertTrue(isValid(Group.NO_GROUP, recipient, 123L, Asset.QORT));
|
||||
|
||||
// with recipient, no amount
|
||||
assertTrue(isValid(Group.NO_GROUP, recipient, 0L, null));
|
||||
|
||||
// no recipient (message to group), no amount
|
||||
assertTrue(isValid(Group.NO_GROUP, null, 0L, null));
|
||||
|
||||
// can't have amount if no recipient!
|
||||
assertFalse(isValid(Group.NO_GROUP, null, 123L, Asset.QORT));
|
||||
|
||||
// Alice is part of group 1
|
||||
assertTrue(isValid(1, null, 0L, null));
|
||||
|
||||
int newGroupId;
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
newGroupId = GroupUtils.createGroup(repository, "chloe", "non-alice-group", false, ApprovalThreshold.ONE, 10, 1440);
|
||||
}
|
||||
|
||||
// Alice is not part of new group
|
||||
assertFalse(isValid(newGroupId, null, 0L, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withRecipentNoAmount() throws DataException {
|
||||
testMessage(Group.NO_GROUP, recipient, 0L, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withRecipentWithAmount() throws DataException {
|
||||
testMessage(Group.NO_GROUP, recipient, 123L, Asset.QORT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noRecipentNoAmount() throws DataException {
|
||||
testMessage(Group.NO_GROUP, null, 0L, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noRecipentNoAmountWithGroup() throws DataException {
|
||||
testMessage(1, null, 0L, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serializationTests() throws DataException, TransformationException {
|
||||
// with recipient, with amount
|
||||
testSerialization(recipient, 123L, Asset.QORT);
|
||||
|
||||
// with recipient, no amount
|
||||
testSerialization(recipient, 0L, null);
|
||||
|
||||
// no recipient (message to group), no amount
|
||||
testSerialization(null, 0L, null);
|
||||
}
|
||||
|
||||
private boolean isValid(int txGroupId, String recipient, long amount, Long assetId) throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
TestAccount alice = Common.getTestAccount(repository, "alice");
|
||||
|
||||
MessageTransactionData transactionData = new MessageTransactionData(TestTransaction.generateBase(alice, txGroupId),
|
||||
version, recipient, amount, assetId, new byte[1], false, false);
|
||||
|
||||
Transaction transaction = new MessageTransaction(repository, transactionData);
|
||||
|
||||
return transaction.isValidUnconfirmed() == ValidationResult.OK;
|
||||
}
|
||||
}
|
||||
|
||||
private void testMessage(int txGroupId, String recipient, long amount, Long assetId) throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
TestAccount alice = Common.getTestAccount(repository, "alice");
|
||||
|
||||
MessageTransactionData transactionData = new MessageTransactionData(TestTransaction.generateBase(alice, txGroupId),
|
||||
version, recipient, amount, assetId, new byte[1], false, false);
|
||||
|
||||
TransactionUtils.signAndMint(repository, transactionData, alice);
|
||||
|
||||
BlockUtils.orphanLastBlock(repository);
|
||||
}
|
||||
}
|
||||
|
||||
private void testSerialization(String recipient, long amount, Long assetId) throws DataException, TransformationException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
TestAccount alice = Common.getTestAccount(repository, "alice");
|
||||
|
||||
MessageTransactionData expectedTransactionData = new MessageTransactionData(TestTransaction.generateBase(alice),
|
||||
version, recipient, amount, assetId, new byte[1], false, false);
|
||||
|
||||
Transaction transaction = new MessageTransaction(repository, expectedTransactionData);
|
||||
transaction.sign(alice);
|
||||
|
||||
MessageTransactionTransformer.getDataLength(expectedTransactionData);
|
||||
byte[] transactionBytes = MessageTransactionTransformer.toBytes(expectedTransactionData);
|
||||
|
||||
TransactionData transactionData = TransactionTransformer.fromBytes(transactionBytes);
|
||||
assertEquals(TransactionType.MESSAGE, transactionData.getType());
|
||||
|
||||
MessageTransactionData actualTransactionData = (MessageTransactionData) transactionData;
|
||||
|
||||
assertEquals(expectedTransactionData.getRecipient(), actualTransactionData.getRecipient());
|
||||
assertEquals(expectedTransactionData.getAmount(), actualTransactionData.getAmount());
|
||||
assertEquals(expectedTransactionData.getAssetId(), actualTransactionData.getAssetId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -474,9 +474,10 @@ public class AtTests extends Common {
|
||||
|
||||
Long fee = null;
|
||||
long amount = 0;
|
||||
Long assetId = null; // because amount is zero
|
||||
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(txTimestamp, Group.NO_GROUP, lastReference, sender.getPublicKey(), fee, null);
|
||||
TransactionData messageTransactionData = new MessageTransactionData(baseTransactionData, 4, recipient, Asset.QORT, amount, data, false, false);
|
||||
TransactionData messageTransactionData = new MessageTransactionData(baseTransactionData, 4, recipient, amount, assetId, data, false, false);
|
||||
|
||||
MessageTransaction messageTransaction = new MessageTransaction(repository, messageTransactionData);
|
||||
|
||||
|
@ -19,7 +19,7 @@ public class MessageTestTransaction extends TestTransaction {
|
||||
final boolean isText = true;
|
||||
final boolean isEncrypted = false;
|
||||
|
||||
return new MessageTransactionData(generateBase(account), version, recipient, assetId, amount, data, isText, isEncrypted);
|
||||
return new MessageTransactionData(generateBase(account), version, recipient, amount, assetId, data, isText, isEncrypted);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,8 +12,12 @@ public abstract class TestTransaction {
|
||||
|
||||
protected static final Random random = new Random();
|
||||
|
||||
public static BaseTransactionData generateBase(PrivateKeyAccount account, int txGroupId) throws DataException {
|
||||
return new BaseTransactionData(System.currentTimeMillis(), txGroupId, account.getLastReference(), account.getPublicKey(), BlockChain.getInstance().getUnitFee(), null);
|
||||
}
|
||||
|
||||
public static BaseTransactionData generateBase(PrivateKeyAccount account) throws DataException {
|
||||
return new BaseTransactionData(System.currentTimeMillis(), Group.NO_GROUP, account.getLastReference(), account.getPublicKey(), BlockChain.getInstance().getUnitFee(), null);
|
||||
return generateBase(account, Group.NO_GROUP);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user