Merge branch 'message-wo-recipient' into launch

This commit is contained in:
catbref 2020-05-18 10:12:54 +01:00
commit a7b9215ace
10 changed files with 273 additions and 47 deletions

View File

@ -815,9 +815,10 @@ public class CrossChainResource {
Long fee = null; Long fee = null;
long amount = 0L; long amount = 0L;
Long assetId = null; // no assetId as amount is zero
BaseTransactionData baseTransactionData = new BaseTransactionData(txTimestamp, Group.NO_GROUP, lastReference, senderPublicKey, fee, null); 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); MessageTransaction messageTransaction = new MessageTransaction(repository, messageTransactionData);

View File

@ -5,7 +5,6 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.qortal.asset.Asset;
import org.qortal.transaction.Transaction.TransactionType; import org.qortal.transaction.Transaction.TransactionType;
import io.swagger.v3.oas.annotations.media.Schema; 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 { public class MessageTransactionData extends TransactionData {
// Properties // Properties
private byte[] senderPublicKey; private byte[] senderPublicKey;
private int version; private int version;
// Not always present
private String recipient; private String recipient;
private Long assetId;
@XmlJavaTypeAdapter(value = org.qortal.api.AmountTypeAdapter.class) @XmlJavaTypeAdapter(value = org.qortal.api.AmountTypeAdapter.class)
private long amount; private long amount;
// Not present if amount is zero
private Long assetId;
private byte[] data; private byte[] data;
private boolean isText; private boolean isText;
private boolean isEncrypted; private boolean isEncrypted;
// Constructors // Constructors
@ -38,19 +47,14 @@ public class MessageTransactionData extends TransactionData {
} }
public MessageTransactionData(BaseTransactionData baseTransactionData, 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); super(TransactionType.MESSAGE, baseTransactionData);
this.senderPublicKey = baseTransactionData.creatorPublicKey; this.senderPublicKey = baseTransactionData.creatorPublicKey;
this.version = version; this.version = version;
this.recipient = recipient; this.recipient = recipient;
if (assetId != null)
this.assetId = assetId;
else
this.assetId = Asset.QORT;
this.amount = amount; this.amount = amount;
this.assetId = assetId;
this.data = data; this.data = data;
this.isText = isText; this.isText = isText;
this.isEncrypted = isEncrypted; this.isEncrypted = isEncrypted;
@ -70,23 +74,23 @@ public class MessageTransactionData extends TransactionData {
return this.recipient; return this.recipient;
} }
public Long getAssetId() {
return this.assetId;
}
public long getAmount() { public long getAmount() {
return this.amount; return this.amount;
} }
public Long getAssetId() {
return this.assetId;
}
public byte[] getData() { public byte[] getData() {
return this.data; return this.data;
} }
public boolean getIsText() { public boolean isText() {
return this.isText; return this.isText;
} }
public boolean getIsEncrypted() { public boolean isEncrypted() {
return this.isEncrypted; return this.isEncrypted;
} }

View File

@ -269,8 +269,8 @@ public class HSQLDBDatabaseUpdates {
case 6: case 6:
// Message Transactions // Message Transactions
stmt.execute("CREATE TABLE MessageTransactions (signature Signature, version TINYINT NOT NULL, " stmt.execute("CREATE TABLE MessageTransactions (signature Signature, version TINYINT NOT NULL, "
+ "sender QortalPublicKey NOT NULL, recipient QortalAddress 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, amount QortalAmount NOT NULL, asset_id AssetID NOT NULL, data MessageData NOT NULL, " + "is_text BOOLEAN NOT NULL, is_encrypted BOOLEAN NOT NULL, data MessageData NOT NULL, "
+ TRANSACTION_KEYS + ")"); + TRANSACTION_KEYS + ")");
break; break;

View File

@ -36,7 +36,7 @@ public class HSQLDBMessageTransactionRepository extends HSQLDBTransactionReposit
byte[] data = resultSet.getBytes(7); 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) { } catch (SQLException e) {
throw new DataException("Unable to fetch message transaction from repository", 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()) saveHelper.bind("signature", messageTransactionData.getSignature()).bind("version", messageTransactionData.getVersion())
.bind("sender", messageTransactionData.getSenderPublicKey()).bind("recipient", messageTransactionData.getRecipient()) .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("amount", messageTransactionData.getAmount()).bind("asset_id", messageTransactionData.getAssetId())
.bind("data", messageTransactionData.getData()); .bind("data", messageTransactionData.getData());

View File

@ -4,6 +4,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.qortal.account.Account; import org.qortal.account.Account;
import org.qortal.asset.Asset;
import org.qortal.data.PaymentData; import org.qortal.data.PaymentData;
import org.qortal.data.transaction.MessageTransactionData; import org.qortal.data.transaction.MessageTransactionData;
import org.qortal.data.transaction.TransactionData; import org.qortal.data.transaction.TransactionData;
@ -13,14 +14,17 @@ import org.qortal.repository.Repository;
public class MessageTransaction extends Transaction { public class MessageTransaction extends Transaction {
// Useful constants
public static final int MAX_DATA_SIZE = 4000;
// Properties // Properties
private MessageTransactionData messageTransactionData; private MessageTransactionData messageTransactionData;
/** Cached, lazy-instantiated payment data. Use {@link #getPaymentData()} instead! */
private PaymentData paymentData = null; private PaymentData paymentData = null;
// Other useful constants
public static final int MAX_DATA_SIZE = 4000;
private static final boolean isZeroAmountValid = true;
// Constructors // Constructors
@ -34,6 +38,9 @@ public class MessageTransaction extends Transaction {
@Override @Override
public List<String> getRecipientAddresses() throws DataException { public List<String> getRecipientAddresses() throws DataException {
if (this.messageTransactionData.getRecipient() == null)
return Collections.emptyList();
return Collections.singletonList(this.messageTransactionData.getRecipient()); 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) if (this.messageTransactionData.getData().length < 1 || this.messageTransactionData.getData().length > MAX_DATA_SIZE)
return ValidationResult.INVALID_DATA_LENGTH; 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 // Wrap and delegate final payment checks to Payment class
return new Payment(this.repository).isValid(this.messageTransactionData.getSenderPublicKey(), getPaymentData(), this.messageTransactionData.getFee(), return new Payment(this.repository).isValid(this.messageTransactionData.getSenderPublicKey(), getPaymentData(),
isZeroAmountValid); this.messageTransactionData.getFee(), true);
} }
@Override @Override
public ValidationResult isProcessable() throws DataException { 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 // Wrap and delegate final processable checks to Payment class
return new Payment(this.repository).isProcessable(this.messageTransactionData.getSenderPublicKey(), getPaymentData(), this.messageTransactionData.getFee(), return new Payment(this.repository).isProcessable(this.messageTransactionData.getSenderPublicKey(),
isZeroAmountValid); getPaymentData(), this.messageTransactionData.getFee(), true);
} }
@Override @Override
public void process() throws DataException { 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. // Wrap and delegate payment processing to Payment class.
new Payment(this.repository).process(this.messageTransactionData.getSenderPublicKey(), getPaymentData()); new Payment(this.repository).process(this.messageTransactionData.getSenderPublicKey(), getPaymentData());
} }
@Override @Override
public void processReferencesAndFees() throws DataException { 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. // 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(), new Payment(this.repository).processReferencesAndFees(this.messageTransactionData.getSenderPublicKey(),
this.messageTransactionData.getSignature(), false); getPaymentData(), this.messageTransactionData.getFee(), this.messageTransactionData.getSignature(),
false);
} }
@Override @Override
public void orphan() throws DataException { 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. // Wrap and delegate payment processing to Payment class.
new Payment(this.repository).orphan(this.messageTransactionData.getSenderPublicKey(), getPaymentData()); new Payment(this.repository).orphan(this.messageTransactionData.getSenderPublicKey(), getPaymentData());
} }
@Override @Override
public void orphanReferencesAndFees() throws DataException { 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. // 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(), new Payment(this.repository).orphanReferencesAndFees(this.messageTransactionData.getSenderPublicKey(),
this.messageTransactionData.getSignature(), this.messageTransactionData.getReference(), false); getPaymentData(), this.messageTransactionData.getFee(), this.messageTransactionData.getSignature(),
this.messageTransactionData.getReference(), false);
} }
} }

View File

@ -19,12 +19,13 @@ import com.google.common.primitives.Longs;
public class MessageTransactionTransformer extends TransactionTransformer { public class MessageTransactionTransformer extends TransactionTransformer {
// Property lengths // Property lengths
private static final int HAS_RECIPIENT_LENGTH = BOOLEAN_LENGTH;
private static final int RECIPIENT_LENGTH = ADDRESS_LENGTH; private static final int RECIPIENT_LENGTH = ADDRESS_LENGTH;
private static final int DATA_SIZE_LENGTH = INT_LENGTH; private static final int DATA_SIZE_LENGTH = INT_LENGTH;
private static final int IS_TEXT_LENGTH = BOOLEAN_LENGTH; private static final int IS_TEXT_LENGTH = BOOLEAN_LENGTH;
private static final int IS_ENCRYPTED_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; protected static final TransactionLayout layout;
@ -35,9 +36,10 @@ public class MessageTransactionTransformer extends TransactionTransformer {
layout.add("transaction's groupID", TransformationType.INT); layout.add("transaction's groupID", TransformationType.INT);
layout.add("reference", TransformationType.SIGNATURE); layout.add("reference", TransformationType.SIGNATURE);
layout.add("sender's public key", TransformationType.PUBLIC_KEY); layout.add("sender's public key", TransformationType.PUBLIC_KEY);
layout.add("recipient", TransformationType.ADDRESS); layout.add("has recipient?", TransformationType.BOOLEAN);
layout.add("asset ID of payment", TransformationType.LONG); layout.add("? recipient", TransformationType.ADDRESS);
layout.add("payment (can be zero)", TransformationType.AMOUNT); 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 length", TransformationType.INT);
layout.add("message", TransformationType.DATA); layout.add("message", TransformationType.DATA);
layout.add("is message encrypted?", TransformationType.BOOLEAN); layout.add("is message encrypted?", TransformationType.BOOLEAN);
@ -58,12 +60,13 @@ public class MessageTransactionTransformer extends TransactionTransformer {
byte[] senderPublicKey = Serialization.deserializePublicKey(byteBuffer); byte[] senderPublicKey = Serialization.deserializePublicKey(byteBuffer);
String recipient = Serialization.deserializeAddress(byteBuffer); boolean hasRecipient = byteBuffer.get() != 0;
String recipient = hasRecipient ? Serialization.deserializeAddress(byteBuffer) : null;
long assetId = byteBuffer.getLong();
long amount = byteBuffer.getLong(); long amount = byteBuffer.getLong();
Long assetId = amount != 0 ? byteBuffer.getLong() : null;
int dataSize = byteBuffer.getInt(); int dataSize = byteBuffer.getInt();
// Don't allow invalid dataSize here to avoid run-time issues // Don't allow invalid dataSize here to avoid run-time issues
if (dataSize > MessageTransaction.MAX_DATA_SIZE) 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); 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 { public static int getDataLength(TransactionData transactionData) throws TransformationException {
MessageTransactionData messageTransactionData = (MessageTransactionData) transactionData; 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 { public static byte[] toBytes(TransactionData transactionData) throws TransformationException {
@ -100,19 +111,25 @@ public class MessageTransactionTransformer extends TransactionTransformer {
transformCommonBytes(transactionData, bytes); transformCommonBytes(transactionData, bytes);
Serialization.serializeAddress(bytes, messageTransactionData.getRecipient()); if (messageTransactionData.getRecipient() != null) {
bytes.write((byte) 1);
bytes.write(Longs.toByteArray(messageTransactionData.getAssetId())); Serialization.serializeAddress(bytes, messageTransactionData.getRecipient());
} else {
bytes.write((byte) 0);
}
bytes.write(Longs.toByteArray(messageTransactionData.getAmount())); 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(Ints.toByteArray(messageTransactionData.getData().length));
bytes.write(messageTransactionData.getData()); 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())); bytes.write(Longs.toByteArray(messageTransactionData.getFee()));

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

View File

@ -474,9 +474,10 @@ public class AtTests extends Common {
Long fee = null; Long fee = null;
long amount = 0; long amount = 0;
Long assetId = null; // because amount is zero
BaseTransactionData baseTransactionData = new BaseTransactionData(txTimestamp, Group.NO_GROUP, lastReference, sender.getPublicKey(), fee, null); 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); MessageTransaction messageTransaction = new MessageTransaction(repository, messageTransactionData);

View File

@ -19,7 +19,7 @@ public class MessageTestTransaction extends TestTransaction {
final boolean isText = true; final boolean isText = true;
final boolean isEncrypted = false; 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);
} }
} }

View File

@ -12,8 +12,12 @@ public abstract class TestTransaction {
protected static final Random random = new Random(); 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 { 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);
} }
} }