mirror of
https://github.com/Qortal/qortal.git
synced 2025-07-23 04:36:50 +00:00
MAJOR: Don't delete transactions when orphaning - make them unconfirmed again
Lots of edits to Transaction subclasses to change/remove 'delete'. Corresponding extra changes to help reset some transaction fields to pre-process state during orphaning. Changed Block, GenesisBlock & Synchronizer to save transactions where appropriate. Added enhanced GET_SIGNATURES_V2 network message to reduce the number of block signatures sent over network. Peers are now version 2 if they send a new-style build version string, instead of using first digit from build version.
This commit is contained in:
@@ -3,23 +3,37 @@ package org.qora.test;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.qora.account.PrivateKeyAccount;
|
||||
import org.qora.block.Block;
|
||||
import org.qora.block.BlockGenerator;
|
||||
import org.qora.block.GenesisBlock;
|
||||
import org.qora.data.at.ATStateData;
|
||||
import org.qora.data.block.BlockData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
import org.qora.repository.RepositoryManager;
|
||||
import org.qora.test.common.Common;
|
||||
import org.qora.test.common.TransactionUtils;
|
||||
import org.qora.transaction.Transaction;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
import org.qora.transform.TransformationException;
|
||||
import org.qora.transform.block.BlockTransformer;
|
||||
import org.qora.transform.transaction.TransactionTransformer;
|
||||
import org.qora.utils.Base58;
|
||||
import org.qora.utils.Triple;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class BlockTests extends Common {
|
||||
|
||||
@Before
|
||||
public void beforeTest() throws DataException {
|
||||
Common.useDefaultSettings();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenesisBlockTransactions() throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
@@ -33,20 +47,24 @@ public class BlockTests extends Common {
|
||||
List<Transaction> transactions = block.getTransactions();
|
||||
assertNotNull(transactions);
|
||||
|
||||
byte[] lastGenesisSignature = null;
|
||||
for (Transaction transaction : transactions) {
|
||||
assertNotNull(transaction);
|
||||
|
||||
TransactionData transactionData = transaction.getTransactionData();
|
||||
|
||||
assertEquals(Transaction.TransactionType.GENESIS, transactionData.getType());
|
||||
if (transactionData.getType() != Transaction.TransactionType.GENESIS)
|
||||
continue;
|
||||
|
||||
assertTrue(transactionData.getFee().compareTo(BigDecimal.ZERO) == 0);
|
||||
assertNull(transactionData.getReference());
|
||||
assertTrue(transaction.isSignatureValid());
|
||||
assertEquals(Transaction.ValidationResult.OK, transaction.isValid());
|
||||
|
||||
lastGenesisSignature = transactionData.getSignature();
|
||||
}
|
||||
|
||||
// Attempt to load first transaction directly from database
|
||||
TransactionData transactionData = repository.getTransactionRepository().fromSignature(transactions.get(0).getTransactionData().getSignature());
|
||||
// Attempt to load last GENESIS transaction directly from database
|
||||
TransactionData transactionData = repository.getTransactionRepository().fromSignature(lastGenesisSignature);
|
||||
assertNotNull(transactionData);
|
||||
|
||||
assertEquals(Transaction.TransactionType.GENESIS, transactionData.getType());
|
||||
@@ -61,61 +79,59 @@ public class BlockTests extends Common {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockPaymentTransactions() throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
// Block 949 has lots of varied transactions
|
||||
// Blocks 390 & 754 have only payment transactions
|
||||
BlockData blockData = repository.getBlockRepository().fromHeight(754);
|
||||
assertNotNull("Block 754 is required for this test", blockData);
|
||||
|
||||
Block block = new Block(repository, blockData);
|
||||
assertTrue(block.isSignatureValid());
|
||||
|
||||
List<Transaction> transactions = block.getTransactions();
|
||||
assertNotNull(transactions);
|
||||
|
||||
for (Transaction transaction : transactions) {
|
||||
assertNotNull(transaction);
|
||||
|
||||
TransactionData transactionData = transaction.getTransactionData();
|
||||
|
||||
assertEquals(Transaction.TransactionType.PAYMENT, transactionData.getType());
|
||||
assertFalse(transactionData.getFee().compareTo(BigDecimal.ZERO) == 0);
|
||||
assertNotNull(transactionData.getReference());
|
||||
|
||||
assertTrue(transaction.isSignatureValid());
|
||||
}
|
||||
|
||||
// Attempt to load first transaction directly from database
|
||||
TransactionData transactionData = repository.getTransactionRepository().fromSignature(transactions.get(0).getTransactionData().getSignature());
|
||||
assertNotNull(transactionData);
|
||||
|
||||
assertEquals(Transaction.TransactionType.PAYMENT, transactionData.getType());
|
||||
assertFalse(transactionData.getFee().compareTo(BigDecimal.ZERO) == 0);
|
||||
assertNotNull(transactionData.getReference());
|
||||
|
||||
Transaction transaction = Transaction.fromData(repository, transactionData);
|
||||
assertNotNull(transaction);
|
||||
|
||||
assertTrue(transaction.isSignatureValid());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockSerialization() throws DataException, TransformationException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
// Block 949 has lots of varied transactions
|
||||
// Blocks 390 & 754 have only payment transactions
|
||||
BlockData blockData = repository.getBlockRepository().fromHeight(754);
|
||||
assertNotNull("Block 754 is required for this test", blockData);
|
||||
PrivateKeyAccount signingAccount = Common.getTestAccount(repository, "alice");
|
||||
|
||||
// TODO: Fill block with random, valid transactions of every type (except GENESIS or AT)
|
||||
for (Transaction.TransactionType txType : Transaction.TransactionType.values()) {
|
||||
if (txType == TransactionType.GENESIS || txType == TransactionType.AT)
|
||||
continue;
|
||||
|
||||
TransactionData transactionData = TransactionUtils.randomTransaction(repository, signingAccount, txType, true);
|
||||
Transaction transaction = Transaction.fromData(repository, transactionData);
|
||||
transaction.sign(signingAccount);
|
||||
|
||||
repository.getTransactionRepository().save(transactionData);
|
||||
repository.getTransactionRepository().unconfirmTransaction(transactionData);
|
||||
repository.saveChanges();
|
||||
|
||||
// TODO: more transactions
|
||||
break;
|
||||
}
|
||||
|
||||
// We might need to wait until transactions' timestamps are valid for the block we're about to generate
|
||||
try {
|
||||
Thread.sleep(1L);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
BlockGenerator.generateTestingBlock(repository, signingAccount);
|
||||
|
||||
BlockData blockData = repository.getBlockRepository().getLastBlock();
|
||||
Block block = new Block(repository, blockData);
|
||||
assertTrue(block.isSignatureValid());
|
||||
|
||||
byte[] bytes = BlockTransformer.toBytes(block);
|
||||
|
||||
assertEquals(BlockTransformer.getDataLength(block), bytes.length);
|
||||
|
||||
Triple<BlockData, List<TransactionData>, List<ATStateData>> blockInfo = BlockTransformer.fromBytes(bytes);
|
||||
|
||||
// Compare transactions
|
||||
List<TransactionData> deserializedTransactions = blockInfo.getB();
|
||||
assertEquals("Transaction count differs", blockData.getTransactionCount(), deserializedTransactions.size());
|
||||
|
||||
for (int i = 0; i < blockData.getTransactionCount(); ++i) {
|
||||
TransactionData deserializedTransactionData = deserializedTransactions.get(i);
|
||||
Transaction originalTransaction = block.getTransactions().get(i);
|
||||
TransactionData originalTransactionData = originalTransaction.getTransactionData();
|
||||
|
||||
assertEquals("Transaction signature differs", Base58.encode(originalTransactionData.getSignature()), Base58.encode(deserializedTransactionData.getSignature()));
|
||||
assertEquals("Transaction declared length differs", TransactionTransformer.getDataLength(originalTransactionData), TransactionTransformer.getDataLength(deserializedTransactionData));
|
||||
assertEquals("Transaction serialized length differs", TransactionTransformer.toBytes(originalTransactionData).length, TransactionTransformer.toBytes(deserializedTransactionData).length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,15 +0,0 @@
|
||||
package org.qora.test;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.qora.block.BlockChain;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.test.common.Common;
|
||||
|
||||
public class BlockchainTests extends Common {
|
||||
|
||||
@Test
|
||||
public void testValidateOrRebuild() throws DataException {
|
||||
BlockChain.validate();
|
||||
}
|
||||
|
||||
}
|
@@ -1,54 +0,0 @@
|
||||
package org.qora.test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.qora.block.Block;
|
||||
import org.qora.block.GenesisBlock;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
import org.qora.repository.RepositoryManager;
|
||||
import org.qora.test.common.Common;
|
||||
import org.qora.transaction.Transaction;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class GenesisTests extends Common {
|
||||
|
||||
@Test
|
||||
public void testGenesisBlockTransactions() throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
assertEquals("Blockchain should be empty for this test", 0, repository.getBlockRepository().getBlockchainHeight());
|
||||
|
||||
GenesisBlock block = GenesisBlock.getInstance(repository);
|
||||
|
||||
assertNotNull("No genesis block?", block);
|
||||
assertTrue(block.isSignatureValid());
|
||||
// Note: only true if blockchain is empty
|
||||
assertEquals("Block invalid", Block.ValidationResult.OK, block.isValid());
|
||||
|
||||
List<Transaction> transactions = block.getTransactions();
|
||||
assertNotNull("No transactions?", transactions);
|
||||
|
||||
for (Transaction transaction : transactions) {
|
||||
assertNotNull(transaction);
|
||||
|
||||
TransactionData transactionData = transaction.getTransactionData();
|
||||
|
||||
assertEquals(Transaction.TransactionType.GENESIS, transactionData.getType());
|
||||
assertTrue(transactionData.getFee().compareTo(BigDecimal.ZERO) == 0);
|
||||
assertNull(transactionData.getReference());
|
||||
assertNotNull(transactionData.getSignature());
|
||||
assertTrue(transaction.isSignatureValid());
|
||||
assertEquals(Transaction.ValidationResult.OK, transaction.isValid());
|
||||
}
|
||||
|
||||
// Actually try to process genesis block onto empty blockchain
|
||||
block.process();
|
||||
repository.saveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,93 +0,0 @@
|
||||
package org.qora.test;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.qora.account.PublicKeyAccount;
|
||||
import org.qora.data.transaction.PaymentTransactionData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
import org.qora.repository.RepositoryManager;
|
||||
import org.qora.repository.TransactionRepository;
|
||||
import org.qora.test.common.Common;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
import org.qora.utils.Base58;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class LoadTests extends Common {
|
||||
|
||||
@Test
|
||||
public void testLoadPaymentTransaction() throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
TransactionRepository transactionRepository = repository.getTransactionRepository();
|
||||
|
||||
assertTrue("Migrate from old database to at least block 49778 before running this test", repository.getBlockRepository().getBlockchainHeight() >= 49778);
|
||||
|
||||
String signature58 = "1211ZPwG3hk5evWzXCZi9hMDRpwumWmkENjwWkeTCik9xA5uoYnxzF7rwR5hmHH3kG2RXo7ToCAaRc7dvnynByJt";
|
||||
byte[] signature = Base58.decode(signature58);
|
||||
|
||||
TransactionData transactionData = transactionRepository.fromSignature(signature);
|
||||
assertNotNull("Transaction data not loaded from repository", transactionData);
|
||||
assertEquals("Transaction data not PAYMENT type", TransactionType.PAYMENT, transactionData.getType());
|
||||
assertEquals("QXwu8924WdgPoRmtiWQBUMF6eedmp1Hu2E", PublicKeyAccount.getAddress(transactionData.getCreatorPublicKey()));
|
||||
|
||||
PaymentTransactionData paymentTransactionData = (PaymentTransactionData) transactionData;
|
||||
|
||||
assertNotNull(paymentTransactionData);
|
||||
assertEquals("QXwu8924WdgPoRmtiWQBUMF6eedmp1Hu2E", PublicKeyAccount.getAddress(paymentTransactionData.getSenderPublicKey()));
|
||||
assertEquals("QZsv8vbJ6QfrBNba4LMp5UtHhAzhrxvVUU", paymentTransactionData.getRecipient());
|
||||
assertEquals(1416209264000L, paymentTransactionData.getTimestamp());
|
||||
assertEquals("31dC6kHHBeG5vYb8LMaZDjLEmhc9kQB2VUApVd8xWncSRiXu7yMejdprjYFMP2rUnzZxWd4KJhkq6LsV7rQvU1kY",
|
||||
Base58.encode(paymentTransactionData.getReference()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadFactory() throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
TransactionRepository transactionRepository = repository.getTransactionRepository();
|
||||
|
||||
assertTrue("Migrate from old database to at least block 49778 before running this test", repository.getBlockRepository().getBlockchainHeight() >= 49778);
|
||||
|
||||
String signature58 = "1211ZPwG3hk5evWzXCZi9hMDRpwumWmkENjwWkeTCik9xA5uoYnxzF7rwR5hmHH3kG2RXo7ToCAaRc7dvnynByJt";
|
||||
byte[] signature = Base58.decode(signature58);
|
||||
|
||||
while (true) {
|
||||
TransactionData transactionData = transactionRepository.fromSignature(signature);
|
||||
if (transactionData == null)
|
||||
break;
|
||||
|
||||
if (transactionData.getType() != TransactionType.PAYMENT)
|
||||
break;
|
||||
|
||||
PaymentTransactionData paymentTransactionData = (PaymentTransactionData) transactionData;
|
||||
System.out.println(PublicKeyAccount.getAddress(paymentTransactionData.getSenderPublicKey()) + " sent " + paymentTransactionData.getAmount()
|
||||
+ " QORA to " + paymentTransactionData.getRecipient());
|
||||
|
||||
signature = transactionData.getReference();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadNonexistentTransaction() throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
TransactionRepository transactionRepository = repository.getTransactionRepository();
|
||||
|
||||
String signature58 = "1111222233334444";
|
||||
byte[] signature = Base58.decode(signature58);
|
||||
|
||||
TransactionData transactionData = transactionRepository.fromSignature(signature);
|
||||
|
||||
if (transactionData != null) {
|
||||
PaymentTransactionData paymentTransactionData = (PaymentTransactionData) transactionData;
|
||||
|
||||
System.out.println(PublicKeyAccount.getAddress(paymentTransactionData.getSenderPublicKey()) + " sent " + paymentTransactionData.getAmount()
|
||||
+ " QORA to " + paymentTransactionData.getRecipient());
|
||||
|
||||
fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
package org.qora.test;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.qora.data.block.BlockData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
import org.qora.repository.RepositoryManager;
|
||||
import org.qora.repository.TransactionRepository;
|
||||
import org.qora.test.common.Common;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
import org.qora.utils.Base58;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class NavigationTests extends Common {
|
||||
|
||||
@Test
|
||||
public void testNavigateFromTransactionToBlock() throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
TransactionRepository transactionRepository = repository.getTransactionRepository();
|
||||
|
||||
assertTrue("Migrate from old database to at least block 49778 before running this test", repository.getBlockRepository().getBlockchainHeight() >= 49778);
|
||||
|
||||
String signature58 = "1211ZPwG3hk5evWzXCZi9hMDRpwumWmkENjwWkeTCik9xA5uoYnxzF7rwR5hmHH3kG2RXo7ToCAaRc7dvnynByJt";
|
||||
byte[] signature = Base58.decode(signature58);
|
||||
|
||||
System.out.println("Navigating to Block from transaction " + signature58);
|
||||
|
||||
TransactionData transactionData = transactionRepository.fromSignature(signature);
|
||||
assertNotNull("Transaction data not loaded from repository", transactionData);
|
||||
assertEquals("Transaction data not PAYMENT type", TransactionType.PAYMENT, transactionData.getType());
|
||||
|
||||
int transactionHeight = transactionRepository.getHeightFromSignature(signature);
|
||||
assertFalse("Transaction not found or transaction's block not found", transactionHeight == 0);
|
||||
assertEquals("Transaction's block height expected to be 49778", 49778, transactionHeight);
|
||||
|
||||
BlockData blockData = repository.getBlockRepository().fromHeight(transactionHeight);
|
||||
assertNotNull("Block 49778 not loaded from database", blockData);
|
||||
System.out.println("Block " + blockData.getHeight() + ", signature: " + Base58.encode(blockData.getSignature()));
|
||||
|
||||
assertEquals((Integer) 49778, blockData.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
package org.qora.test;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.qora.account.Account;
|
||||
import org.qora.asset.Asset;
|
||||
@@ -19,6 +20,11 @@ public class RepositoryTests extends Common {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(RepositoryTests.class);
|
||||
|
||||
@Before
|
||||
public void beforeTest() throws DataException {
|
||||
Common.useDefaultSettings();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRepository() throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
@@ -44,7 +50,7 @@ public class RepositoryTests extends Common {
|
||||
|
||||
@Test
|
||||
public void testAccessAfterClose() throws DataException {
|
||||
try (Repository repository = RepositoryManager.getRepository()) {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
assertNotNull(repository);
|
||||
|
||||
repository.close();
|
||||
@@ -61,17 +67,15 @@ public class RepositoryTests extends Common {
|
||||
|
||||
@Test
|
||||
public void testDeadlock() throws DataException {
|
||||
Common.useDefaultSettings();
|
||||
|
||||
// Open connection 1
|
||||
try (Repository repository1 = RepositoryManager.getRepository()) {
|
||||
try (final Repository repository1 = RepositoryManager.getRepository()) {
|
||||
|
||||
// Do a database 'read'
|
||||
Account account1 = Common.getTestAccount(repository1, "alice");
|
||||
account1.getLastReference();
|
||||
|
||||
// Open connection 2
|
||||
try (Repository repository2 = RepositoryManager.getRepository()) {
|
||||
try (final Repository repository2 = RepositoryManager.getRepository()) {
|
||||
// Update account in 2
|
||||
Account account2 = Common.getTestAccount(repository2, "alice");
|
||||
account2.setConfirmedBalance(Asset.QORA, BigDecimal.valueOf(1234L));
|
||||
|
@@ -3,17 +3,21 @@ package org.qora.test.common;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.qora.account.PrivateKeyAccount;
|
||||
import org.qora.block.BlockGenerator;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.repository.DataException;
|
||||
import org.qora.repository.Repository;
|
||||
import org.qora.transaction.Transaction;
|
||||
import org.qora.transaction.Transaction.TransactionType;
|
||||
import org.qora.transaction.Transaction.ValidationResult;
|
||||
|
||||
public class TransactionUtils {
|
||||
|
||||
public static void signAndForge(Repository repository, TransactionData transactionData, PrivateKeyAccount signingAccount) throws DataException {
|
||||
public static void signAsUnconfirmed(Repository repository, TransactionData transactionData, PrivateKeyAccount signingAccount) throws DataException {
|
||||
Transaction transaction = Transaction.fromData(repository, transactionData);
|
||||
transaction.sign(signingAccount);
|
||||
|
||||
@@ -32,10 +36,29 @@ public class TransactionUtils {
|
||||
repository.getTransactionRepository().save(transactionData);
|
||||
repository.getTransactionRepository().unconfirmTransaction(transactionData);
|
||||
repository.saveChanges();
|
||||
}
|
||||
|
||||
public static void signAndForge(Repository repository, TransactionData transactionData, PrivateKeyAccount signingAccount) throws DataException {
|
||||
signAsUnconfirmed(repository, transactionData, signingAccount);
|
||||
|
||||
// Generate block
|
||||
PrivateKeyAccount generatorAccount = Common.getTestAccount(repository, "alice");
|
||||
BlockGenerator.generateTestingBlock(repository, generatorAccount);
|
||||
}
|
||||
|
||||
public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, TransactionType txType, boolean wantValid) throws DataException {
|
||||
try {
|
||||
Class <?> clazz = Class.forName(String.join("", org.qora.test.common.transaction.Transaction.class.getPackage().getName(), ".", txType.className, "Transaction"));
|
||||
|
||||
try {
|
||||
Method method = clazz.getDeclaredMethod("randomTransaction", Repository.class, PrivateKeyAccount.class, boolean.class);
|
||||
return (TransactionData) method.invoke(null, repository, account, wantValid);
|
||||
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new RuntimeException(String.format("Transaction subclass constructor not found for transaction type \"%s\"", txType.name()), e);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(String.format("Transaction subclass not found for transaction type \"%s\"", txType.name()), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,18 @@
|
||||
package org.qora.test.common.transaction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.qora.account.PrivateKeyAccount;
|
||||
import org.qora.data.transaction.PaymentTransactionData;
|
||||
import org.qora.data.transaction.TransactionData;
|
||||
import org.qora.group.Group;
|
||||
import org.qora.repository.Repository;
|
||||
import org.qora.utils.NTP;
|
||||
|
||||
public class PaymentTransaction {
|
||||
|
||||
public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) {
|
||||
return new PaymentTransactionData(NTP.getTime(), Group.NO_GROUP, new byte[32], account.getPublicKey(), account.getAddress(), BigDecimal.valueOf(123L), BigDecimal.ONE);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,4 @@
|
||||
package org.qora.test.common.transaction;
|
||||
|
||||
public abstract class Transaction {
|
||||
}
|
@@ -22,7 +22,6 @@ import org.qora.transaction.Transaction.ValidationResult;
|
||||
|
||||
public class GrantForgingTests extends Common {
|
||||
|
||||
|
||||
@Before
|
||||
public void beforeTest() throws DataException {
|
||||
Common.useDefaultSettings();
|
||||
|
Reference in New Issue
Block a user