mirror of
https://github.com/Qortal/qortal.git
synced 2025-07-24 10:41:23 +00:00
Added BuyNameTransaction support
Fixed IssueAssetTransactions not being constructed with signature. Fixed incorrect MessageTransactionData constructors. Refactored various transactions to remove duplicate code. e.g. in CancelOrderTransaction.process() use getCreator() instead of explicit repository call. Added name_reference to BuyNameTransactions HSQLDB table. Fixed incorrect SQL in HSQLDBMultiPaymentTransactionRepository. More unit tests! Fixed wrong data length in CancelOrderTransactionTransformer. Fixed wrong data length in CreateOrderTransactionTransformer. Fixed missing payment bytes in MultiPaymentTransactionTransformer.toBytes();
This commit is contained in:
@@ -61,9 +61,9 @@ public class SerializationTests extends Common {
|
||||
|
||||
TransactionData parsedTransactionData = TransactionTransformer.fromBytes(bytes);
|
||||
|
||||
assertTrue(Arrays.equals(transactionData.getSignature(), parsedTransactionData.getSignature()));
|
||||
assertTrue("Transaction signature mismatch", Arrays.equals(transactionData.getSignature(), parsedTransactionData.getSignature()));
|
||||
|
||||
assertEquals(TransactionTransformer.getDataLength(transactionData), bytes.length);
|
||||
assertEquals("Data length mismatch", TransactionTransformer.getDataLength(transactionData), bytes.length);
|
||||
}
|
||||
|
||||
private void testSpecificBlockTransactions(int height, TransactionType type) throws DataException, TransformationException {
|
||||
@@ -84,13 +84,11 @@ public class SerializationTests extends Common {
|
||||
|
||||
@Test
|
||||
public void testPaymentSerialization() throws TransformationException, DataException {
|
||||
// Blocks 390 & 754 have only payment transactions
|
||||
testSpecificBlockTransactions(754, TransactionType.PAYMENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterNameSerialization() throws TransformationException, DataException {
|
||||
// Block 120 has only name registration transactions
|
||||
testSpecificBlockTransactions(120, TransactionType.REGISTER_NAME);
|
||||
}
|
||||
|
||||
@@ -109,12 +107,46 @@ public class SerializationTests extends Common {
|
||||
testSpecificBlockTransactions(741, TransactionType.CANCEL_SELL_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuyNameSerialization() throws TransformationException, DataException {
|
||||
testSpecificBlockTransactions(973, TransactionType.BUY_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatePollSerialization() throws TransformationException, DataException {
|
||||
// Block 10537 has only create poll transactions
|
||||
testSpecificBlockTransactions(10537, TransactionType.CREATE_POLL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVoteOnPollSerialization() throws TransformationException, DataException {
|
||||
testSpecificBlockTransactions(10540, TransactionType.CREATE_POLL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIssueAssetSerialization() throws TransformationException, DataException {
|
||||
testSpecificBlockTransactions(33661, TransactionType.ISSUE_ASSET);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransferAssetSerialization() throws TransformationException, DataException {
|
||||
testSpecificBlockTransactions(39039, TransactionType.TRANSFER_ASSET);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateAssetOrderSerialization() throws TransformationException, DataException {
|
||||
testSpecificBlockTransactions(35611, TransactionType.CREATE_ASSET_ORDER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelAssetOrderSerialization() throws TransformationException, DataException {
|
||||
testSpecificBlockTransactions(36176, TransactionType.CANCEL_ASSET_ORDER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiPaymentSerialization() throws TransformationException, DataException {
|
||||
testSpecificBlockTransactions(34500, TransactionType.MULTIPAYMENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageSerialization() throws TransformationException, DataException {
|
||||
// Message transactions went live block 99000
|
||||
|
@@ -2,6 +2,7 @@ package test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -16,8 +17,10 @@ import data.account.AccountBalanceData;
|
||||
import data.account.AccountData;
|
||||
import data.block.BlockData;
|
||||
import data.naming.NameData;
|
||||
import data.transaction.BuyNameTransactionData;
|
||||
import data.transaction.CancelSellNameTransactionData;
|
||||
import data.transaction.CreatePollTransactionData;
|
||||
import data.transaction.MessageTransactionData;
|
||||
import data.transaction.PaymentTransactionData;
|
||||
import data.transaction.RegisterNameTransactionData;
|
||||
import data.transaction.SellNameTransactionData;
|
||||
@@ -32,8 +35,10 @@ import qora.account.PublicKeyAccount;
|
||||
import qora.assets.Asset;
|
||||
import qora.block.Block;
|
||||
import qora.block.BlockChain;
|
||||
import qora.transaction.BuyNameTransaction;
|
||||
import qora.transaction.CancelSellNameTransaction;
|
||||
import qora.transaction.CreatePollTransaction;
|
||||
import qora.transaction.MessageTransaction;
|
||||
import qora.transaction.PaymentTransaction;
|
||||
import qora.transaction.RegisterNameTransaction;
|
||||
import qora.transaction.SellNameTransaction;
|
||||
@@ -116,6 +121,19 @@ public class TransactionTests {
|
||||
RepositoryManager.closeRepositoryFactory();
|
||||
}
|
||||
|
||||
private Transaction createPayment(PrivateKeyAccount sender, String recipient) throws DataException {
|
||||
// Make a new payment transaction
|
||||
BigDecimal amount = BigDecimal.valueOf(1_000L);
|
||||
BigDecimal fee = BigDecimal.ONE;
|
||||
long timestamp = parentBlockData.getTimestamp() + 1_000;
|
||||
PaymentTransactionData paymentTransactionData = new PaymentTransactionData(sender.getPublicKey(), recipient, amount, fee, timestamp, reference);
|
||||
|
||||
Transaction paymentTransaction = new PaymentTransaction(repository, paymentTransactionData);
|
||||
paymentTransaction.calcSignature(sender);
|
||||
|
||||
return paymentTransaction;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPaymentTransaction() throws DataException {
|
||||
createTestAccounts(null);
|
||||
@@ -360,6 +378,70 @@ public class TransactionTests {
|
||||
parentBlockData = block.getBlockData();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuyNameTransaction() throws DataException {
|
||||
// Register and sell name using another test
|
||||
testSellNameTransaction();
|
||||
|
||||
String name = "test name";
|
||||
NameData originalNameData = this.repository.getNameRepository().fromName(name);
|
||||
String seller = originalNameData.getOwner();
|
||||
|
||||
// Buyer
|
||||
PrivateKeyAccount buyer = new PrivateKeyAccount(repository, recipientSeed);
|
||||
byte[] nameReference = reference;
|
||||
|
||||
// Send buyer some funds so they have a reference
|
||||
Transaction somePaymentTransaction = createPayment(sender, buyer.getAddress());
|
||||
byte[] buyersReference = somePaymentTransaction.getTransactionData().getSignature();
|
||||
|
||||
// Forge new block with transaction
|
||||
Block block = new Block(repository, parentBlockData, generator, null, null);
|
||||
block.addTransaction(somePaymentTransaction.getTransactionData());
|
||||
block.sign();
|
||||
|
||||
block.process();
|
||||
repository.saveChanges();
|
||||
parentBlockData = block.getBlockData();
|
||||
|
||||
BigDecimal fee = BigDecimal.ONE;
|
||||
long timestamp = parentBlockData.getTimestamp() + 1_000;
|
||||
BuyNameTransactionData buyNameTransactionData = new BuyNameTransactionData(buyer.getPublicKey(), name, originalNameData.getSalePrice(), seller,
|
||||
nameReference, fee, timestamp, buyersReference);
|
||||
|
||||
Transaction buyNameTransaction = new BuyNameTransaction(repository, buyNameTransactionData);
|
||||
buyNameTransaction.calcSignature(buyer);
|
||||
assertTrue(buyNameTransaction.isSignatureValid());
|
||||
assertEquals(ValidationResult.OK, buyNameTransaction.isValid());
|
||||
|
||||
// Forge new block with transaction
|
||||
block = new Block(repository, parentBlockData, generator, null, null);
|
||||
block.addTransaction(buyNameTransactionData);
|
||||
block.sign();
|
||||
|
||||
assertTrue("Block signatures invalid", block.isSignatureValid());
|
||||
assertEquals("Block is invalid", Block.ValidationResult.OK, block.isValid());
|
||||
|
||||
block.process();
|
||||
repository.saveChanges();
|
||||
|
||||
// Check name was updated
|
||||
NameData actualNameData = this.repository.getNameRepository().fromName(name);
|
||||
assertFalse(actualNameData.getIsForSale());
|
||||
assertEquals(originalNameData.getSalePrice(), actualNameData.getSalePrice());
|
||||
assertEquals(buyer.getAddress(), actualNameData.getOwner());
|
||||
|
||||
// Now orphan block
|
||||
block.orphan();
|
||||
repository.saveChanges();
|
||||
|
||||
// Check name has been reverted correctly
|
||||
actualNameData = this.repository.getNameRepository().fromName(name);
|
||||
assertTrue(actualNameData.getIsForSale());
|
||||
assertEquals(originalNameData.getSalePrice(), actualNameData.getSalePrice());
|
||||
assertEquals(originalNameData.getOwner(), actualNameData.getOwner());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatePollTransaction() throws DataException {
|
||||
// This test requires GenesisBlock's timestamp is set to something after BlockChain.VOTING_RELEASE_TIMESTAMP
|
||||
@@ -491,4 +573,78 @@ public class TransactionTests {
|
||||
assertTrue("Wrong voter public key", Arrays.equals(sender.getPublicKey(), votes.get(0).getVoterPublicKey()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIssueAssetTransaction() throws DataException {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransferAssetTransaction() throws DataException {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateAssetOrderTransaction() throws DataException {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelAssetOrderTransaction() throws DataException {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiPaymentTransaction() throws DataException {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageTransaction() throws DataException, UnsupportedEncodingException {
|
||||
createTestAccounts(null);
|
||||
|
||||
// Make a new message transaction
|
||||
Account recipient = new PublicKeyAccount(repository, recipientSeed);
|
||||
BigDecimal amount = BigDecimal.valueOf(1_000L);
|
||||
BigDecimal fee = BigDecimal.ONE;
|
||||
long timestamp = parentBlockData.getTimestamp() + 1_000;
|
||||
int version = Transaction.getVersionByTimestamp(timestamp);
|
||||
byte[] data = "test".getBytes("UTF-8");
|
||||
boolean isText = true;
|
||||
boolean isEncrypted = false;
|
||||
|
||||
MessageTransactionData messageTransactionData = new MessageTransactionData(version, sender.getPublicKey(), recipient.getAddress(), Asset.QORA, amount,
|
||||
data, isText, isEncrypted, fee, timestamp, reference);
|
||||
|
||||
Transaction messageTransaction = new MessageTransaction(repository, messageTransactionData);
|
||||
messageTransaction.calcSignature(sender);
|
||||
assertTrue(messageTransaction.isSignatureValid());
|
||||
assertEquals(ValidationResult.OK, messageTransaction.isValid());
|
||||
|
||||
// Forge new block with message transaction
|
||||
Block block = new Block(repository, parentBlockData, generator, null, null);
|
||||
block.addTransaction(messageTransactionData);
|
||||
block.sign();
|
||||
|
||||
assertTrue("Block signatures invalid", block.isSignatureValid());
|
||||
assertEquals("Block is invalid", Block.ValidationResult.OK, block.isValid());
|
||||
|
||||
block.process();
|
||||
repository.saveChanges();
|
||||
|
||||
// Check sender's balance
|
||||
BigDecimal expectedBalance = senderBalance.subtract(amount).subtract(fee);
|
||||
BigDecimal actualBalance = accountRepository.getBalance(sender.getAddress(), Asset.QORA).getBalance();
|
||||
assertTrue("Sender's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0);
|
||||
|
||||
// Fee should be in generator's balance
|
||||
expectedBalance = generatorBalance.add(fee);
|
||||
actualBalance = accountRepository.getBalance(generator.getAddress(), Asset.QORA).getBalance();
|
||||
assertTrue("Generator's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0);
|
||||
|
||||
// Amount should be in recipient's balance
|
||||
expectedBalance = amount;
|
||||
actualBalance = accountRepository.getBalance(recipient.getAddress(), Asset.QORA).getBalance();
|
||||
assertTrue("Recipient's new balance incorrect", expectedBalance.compareTo(actualBalance) == 0);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user