Interim safety commit due to large number of changes!

log4j2.properties now has debugging entries removed.
log4j2-test.properties (not in repo) takes priority
 so using that in development instead.

Unconfirmed transactions no longer wiped on start-up
 by default - see Settings

Reworking of {Public,Private,Genesis}Accounts as it seemed
 possible to silently lose public key in repository.
The use of AccountData didn't work and so field-specific
 repository calls have been made instead
 (e.g. setLastReference) that try to opportunistically
 store public key too, if available (i.e. caller is
 PublicKeyAccount subclass, or better).

Added API call GET /addresses/{address} to return
 general account info in one go. (Essentially the
 AccountData object as fetched from repository).

Initial work on adding default groupID to accounts,
 along with corresponding SET_GROUP transaction type.
In additional, added blockchain-wide default groupID
 and flag to allow/disallow no-group/groupless
 transactions.

Initial work on group-admin approval of transactions
 tied to a specific group via txGroupId.

More work needed on transaction's "effective txGroupId"!

API call /transactions/pending to list transactions
 pending group-admin approval. However, this needs more
 work (see effective txGroupId above) and potentially
 offloading to HSQLDB repository if possible.

Minor CIYAM AT renames to help static reflection initializers.

Block.orphan() no longer adds orphaned transactions back to
 unconfirmed pile as they are themselves deleted during
 Transaction.orphan(). Maybe the answer is to NOT delete
 them during Transaction.orphan() but to add them to
 unconfirmed pile at that point? Very old transactions
 leftover from major resync would simply expire, whereas
 recently transactions leftover from minor resync could
 still make it into a new block on synced chain fork.

Changes/tidying/improvements to block generator regarding
 removing invalid transactions and dealing with transactions
 pending group approval.

Approval threshold added to groups.

Mass refactoring of transaction-related classes to unify
 constructors, particularly field ordering, to fall in line
 with raw transaction layout.
e.g. constructors now reflect that raw transactions mostly
 start with type, timestamp, txGroupId, publicKey, reference
e.g. JAXB afterUnmarshal methods added where needed and corresponding
 nasty code in Transaction subclass constructors ripped out.
e.g. TransactionTransformer subclasses contain less duplicated code.

Fixed bug with repository save points thanks to swapping to Deque.

Some fixes to do with missing transaction types being passed to JAXB
 TransactionData subclass constructors.

Ripped out obsolete toJSON in TransactionTransformers as this
 is all nicely taken care of by Swagger/OpenAPI (thanks @Kc)
This commit is contained in:
catbref
2019-02-18 19:00:37 +00:00
parent 82e9e1e7dc
commit 00656f6724
143 changed files with 2591 additions and 1848 deletions

View File

@@ -6,6 +6,7 @@ import org.qora.data.at.ATStateData;
import org.qora.data.block.BlockData;
import org.qora.data.block.BlockTransactionData;
import org.qora.data.transaction.DeployAtTransactionData;
import org.qora.group.Group;
import org.qora.repository.DataException;
import org.qora.repository.Repository;
import org.qora.repository.RepositoryManager;
@@ -46,8 +47,8 @@ public class ATTests extends Common {
byte[] reference = Base58.decode("2D3jX1pEgu6irsQ7QzJb85QP1D9M45dNyP5M9a3WFHndU5ZywF4F5pnUurcbzMnGMcTwpAY6H7DuLw8cUBU66ao1");
byte[] signature = Base58.decode("2dZ4megUyNoYYY7qWmuSd4xw1yUKgPPF97yBbeddh8aKuC8PLpz7Xvf3r6Zjv1zwGrR8fEAHuaztCPD4KQp76KdL");
DeployAtTransactionData transactionData = new DeployAtTransactionData(creatorPublicKey, name, description, ATType, tags, creationBytes, amount,
Asset.QORA, fee, timestamp, reference, signature);
DeployAtTransactionData transactionData = new DeployAtTransactionData(timestamp, Group.DEFAULT_GROUP, reference, creatorPublicKey, name, description, ATType,
tags, creationBytes, amount, Asset.QORA, fee, signature);
try (final Repository repository = RepositoryManager.getRepository()) {
repository.getTransactionRepository().save(transactionData);

View File

@@ -6,6 +6,7 @@ import java.time.Instant;
import org.junit.jupiter.api.Test;
import org.qora.account.PublicKeyAccount;
import org.qora.data.transaction.PaymentTransactionData;
import org.qora.group.Group;
import org.qora.repository.DataException;
import org.qora.repository.Repository;
import org.qora.repository.RepositoryManager;
@@ -22,8 +23,8 @@ public class SaveTests extends Common {
byte[] signature = Base58.decode(signature58);
PublicKeyAccount sender = new PublicKeyAccount(repository, "Qsender".getBytes());
PaymentTransactionData paymentTransactionData = new PaymentTransactionData(sender.getPublicKey(), "Qrecipient", BigDecimal.valueOf(12345L),
BigDecimal.ONE, Instant.now().getEpochSecond(), reference, signature);
PaymentTransactionData paymentTransactionData = new PaymentTransactionData(Instant.now().getEpochSecond(), Group.DEFAULT_GROUP, reference,
sender.getPublicKey(), "Qrecipient", BigDecimal.valueOf(12345L), BigDecimal.ONE, signature);
repository.getTransactionRepository().save(paymentTransactionData);

View File

@@ -32,6 +32,7 @@ import org.qora.data.transaction.VoteOnPollTransactionData;
import org.qora.data.voting.PollData;
import org.qora.data.voting.PollOptionData;
import org.qora.data.voting.VoteOnPollData;
import org.qora.group.Group;
import org.qora.repository.AccountRepository;
import org.qora.repository.AssetRepository;
import org.qora.repository.DataException;
@@ -120,7 +121,7 @@ public class TransactionTests {
// Create test generator account
generator = new PrivateKeyAccount(repository, generatorSeed);
accountRepository.save(new AccountData(generator.getAddress(), generatorSeed, generator.getPublicKey()));
accountRepository.setLastReference(new AccountData(generator.getAddress(), generatorSeed, generator.getPublicKey(), Group.DEFAULT_GROUP));
accountRepository.save(new AccountBalanceData(generator.getAddress(), Asset.QORA, initialGeneratorBalance));
// Create test sender account
@@ -128,7 +129,7 @@ public class TransactionTests {
// Mock account
reference = senderSeed;
accountRepository.save(new AccountData(sender.getAddress(), reference, sender.getPublicKey()));
accountRepository.setLastReference(new AccountData(sender.getAddress(), reference, sender.getPublicKey(), Group.DEFAULT_GROUP));
// Mock balance
accountRepository.save(new AccountBalanceData(sender.getAddress(), Asset.QORA, initialSenderBalance));
@@ -146,7 +147,7 @@ public class TransactionTests {
BigDecimal amount = genericPaymentAmount;
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
PaymentTransactionData paymentTransactionData = new PaymentTransactionData(sender.getPublicKey(), recipient, amount, fee, timestamp, reference);
PaymentTransactionData paymentTransactionData = new PaymentTransactionData(timestamp, Group.DEFAULT_GROUP, reference, sender.getPublicKey(), recipient, amount, fee);
Transaction paymentTransaction = new PaymentTransaction(repository, paymentTransactionData);
paymentTransaction.sign(sender);
@@ -163,8 +164,8 @@ public class TransactionTests {
BigDecimal amount = BigDecimal.valueOf(1_000L);
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
PaymentTransactionData paymentTransactionData = new PaymentTransactionData(sender.getPublicKey(), recipient.getAddress(), amount, fee, timestamp,
reference);
PaymentTransactionData paymentTransactionData = new PaymentTransactionData(timestamp, Group.DEFAULT_GROUP, reference, sender.getPublicKey(), recipient.getAddress(),
amount, fee);
Transaction paymentTransaction = new PaymentTransaction(repository, paymentTransactionData);
paymentTransaction.sign(sender);
@@ -224,8 +225,8 @@ public class TransactionTests {
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
RegisterNameTransactionData registerNameTransactionData = new RegisterNameTransactionData(sender.getPublicKey(), sender.getAddress(), name, data, fee,
timestamp, reference);
RegisterNameTransactionData registerNameTransactionData = new RegisterNameTransactionData(timestamp, Group.DEFAULT_GROUP, reference, sender.getPublicKey(), sender.getAddress(),
name, data, fee);
Transaction registerNameTransaction = new RegisterNameTransaction(repository, registerNameTransactionData);
registerNameTransaction.sign(sender);
@@ -280,8 +281,8 @@ public class TransactionTests {
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
UpdateNameTransactionData updateNameTransactionData = new UpdateNameTransactionData(sender.getPublicKey(), newOwner.getAddress(), name, newData,
nameReference, fee, timestamp, reference);
UpdateNameTransactionData updateNameTransactionData = new UpdateNameTransactionData(timestamp, Group.DEFAULT_GROUP, reference, sender.getPublicKey(),
newOwner.getAddress(), name, newData, nameReference, fee);
Transaction updateNameTransaction = new UpdateNameTransaction(repository, updateNameTransactionData);
updateNameTransaction.sign(sender);
@@ -326,7 +327,7 @@ public class TransactionTests {
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
SellNameTransactionData sellNameTransactionData = new SellNameTransactionData(sender.getPublicKey(), name, amount, fee, timestamp, reference);
SellNameTransactionData sellNameTransactionData = new SellNameTransactionData(timestamp, Group.DEFAULT_GROUP, reference, sender.getPublicKey(), name, amount, fee);
Transaction sellNameTransaction = new SellNameTransaction(repository, sellNameTransactionData);
sellNameTransaction.sign(sender);
@@ -377,7 +378,7 @@ public class TransactionTests {
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
CancelSellNameTransactionData cancelSellNameTransactionData = new CancelSellNameTransactionData(sender.getPublicKey(), name, fee, timestamp, reference);
CancelSellNameTransactionData cancelSellNameTransactionData = new CancelSellNameTransactionData(timestamp, Group.DEFAULT_GROUP, reference, sender.getPublicKey(), name, fee);
Transaction cancelSellNameTransaction = new CancelSellNameTransaction(repository, cancelSellNameTransactionData);
cancelSellNameTransaction.sign(sender);
@@ -442,8 +443,8 @@ public class TransactionTests {
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
BuyNameTransactionData buyNameTransactionData = new BuyNameTransactionData(buyer.getPublicKey(), name, originalNameData.getSalePrice(), seller,
nameReference, fee, timestamp, buyersReference);
BuyNameTransactionData buyNameTransactionData = new BuyNameTransactionData(timestamp, Group.DEFAULT_GROUP, buyersReference, buyer.getPublicKey(),
name, originalNameData.getSalePrice(), seller, nameReference, fee);
Transaction buyNameTransaction = new BuyNameTransaction(repository, buyNameTransactionData);
buyNameTransaction.sign(buyer);
@@ -495,8 +496,8 @@ public class TransactionTests {
Account recipient = new PublicKeyAccount(repository, recipientSeed);
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
CreatePollTransactionData createPollTransactionData = new CreatePollTransactionData(sender.getPublicKey(), recipient.getAddress(), pollName,
description, pollOptions, fee, timestamp, reference);
CreatePollTransactionData createPollTransactionData = new CreatePollTransactionData(timestamp, Group.DEFAULT_GROUP, reference,
sender.getPublicKey(), recipient.getAddress(), pollName, description, pollOptions, fee);
Transaction createPollTransaction = new CreatePollTransaction(repository, createPollTransactionData);
createPollTransaction.sign(sender);
@@ -549,8 +550,8 @@ public class TransactionTests {
for (int optionIndex = 0; optionIndex <= pollOptionsSize; ++optionIndex) {
// Make a vote-on-poll transaction
VoteOnPollTransactionData voteOnPollTransactionData = new VoteOnPollTransactionData(sender.getPublicKey(), pollName, optionIndex, fee, timestamp,
reference);
VoteOnPollTransactionData voteOnPollTransactionData = new VoteOnPollTransactionData(timestamp, Group.DEFAULT_GROUP, reference, sender.getPublicKey(), pollName,
optionIndex, fee);
Transaction voteOnPollTransaction = new VoteOnPollTransaction(repository, voteOnPollTransactionData);
voteOnPollTransaction.sign(sender);
@@ -621,8 +622,8 @@ public class TransactionTests {
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
IssueAssetTransactionData issueAssetTransactionData = new IssueAssetTransactionData(sender.getPublicKey(), sender.getAddress(), assetName, description,
quantity, isDivisible, fee, timestamp, reference);
IssueAssetTransactionData issueAssetTransactionData = new IssueAssetTransactionData(timestamp, Group.DEFAULT_GROUP, reference, sender.getPublicKey(),
sender.getAddress(), assetName, description, quantity, isDivisible, fee);
Transaction issueAssetTransaction = new IssueAssetTransaction(repository, issueAssetTransactionData);
issueAssetTransaction.sign(sender);
@@ -711,8 +712,8 @@ public class TransactionTests {
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
TransferAssetTransactionData transferAssetTransactionData = new TransferAssetTransactionData(sender.getPublicKey(), recipient.getAddress(), amount,
assetId, fee, timestamp, reference);
TransferAssetTransactionData transferAssetTransactionData = new TransferAssetTransactionData(timestamp, Group.DEFAULT_GROUP, reference,
sender.getPublicKey(), recipient.getAddress(), amount, assetId, fee);
Transaction transferAssetTransaction = new TransferAssetTransaction(repository, transferAssetTransactionData);
transferAssetTransaction.sign(sender);
@@ -816,8 +817,8 @@ public class TransactionTests {
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
CreateAssetOrderTransactionData createOrderTransactionData = new CreateAssetOrderTransactionData(buyer.getPublicKey(), haveAssetId, wantAssetId, amount, price,
fee, timestamp, buyersReference);
CreateAssetOrderTransactionData createOrderTransactionData = new CreateAssetOrderTransactionData(timestamp, Group.DEFAULT_GROUP, buyersReference, buyer.getPublicKey(), haveAssetId,
wantAssetId, amount, price, fee);
Transaction createOrderTransaction = new CreateAssetOrderTransaction(this.repository, createOrderTransactionData);
createOrderTransaction.sign(buyer);
assertTrue(createOrderTransaction.isSignatureValid());
@@ -897,7 +898,7 @@ public class TransactionTests {
BigDecimal fee = BigDecimal.ONE;
long timestamp = parentBlockData.getTimestamp() + 1_000;
byte[] buyersReference = buyer.getLastReference();
CancelAssetOrderTransactionData cancelOrderTransactionData = new CancelAssetOrderTransactionData(buyer.getPublicKey(), orderId, fee, timestamp, buyersReference);
CancelAssetOrderTransactionData cancelOrderTransactionData = new CancelAssetOrderTransactionData(timestamp, Group.DEFAULT_GROUP, buyersReference, buyer.getPublicKey(), orderId, fee);
Transaction cancelOrderTransaction = new CancelAssetOrderTransaction(this.repository, cancelOrderTransactionData);
cancelOrderTransaction.sign(buyer);
@@ -972,8 +973,8 @@ public class TransactionTests {
long timestamp = parentBlockData.getTimestamp() + 1_000;
BigDecimal senderPreTradeWantBalance = sender.getConfirmedBalance(wantAssetId);
CreateAssetOrderTransactionData createOrderTransactionData = new CreateAssetOrderTransactionData(sender.getPublicKey(), haveAssetId, wantAssetId, amount, price,
fee, timestamp, reference);
CreateAssetOrderTransactionData createOrderTransactionData = new CreateAssetOrderTransactionData(timestamp, Group.DEFAULT_GROUP, reference, sender.getPublicKey(), haveAssetId,
wantAssetId, amount, price, fee);
Transaction createOrderTransaction = new CreateAssetOrderTransaction(this.repository, createOrderTransactionData);
createOrderTransaction.sign(sender);
assertTrue(createOrderTransaction.isSignatureValid());
@@ -1081,7 +1082,7 @@ public class TransactionTests {
payments.add(paymentData);
}
MultiPaymentTransactionData multiPaymentTransactionData = new MultiPaymentTransactionData(sender.getPublicKey(), payments, fee, timestamp, reference);
MultiPaymentTransactionData multiPaymentTransactionData = new MultiPaymentTransactionData(timestamp, Group.DEFAULT_GROUP, reference, sender.getPublicKey(), payments, fee);
Transaction multiPaymentTransaction = new MultiPaymentTransaction(repository, multiPaymentTransactionData);
multiPaymentTransaction.sign(sender);
@@ -1150,8 +1151,8 @@ public class TransactionTests {
boolean isText = true;
boolean isEncrypted = false;
MessageTransactionData messageTransactionData = new MessageTransactionData(version, sender.getPublicKey(), recipient.getAddress(), Asset.QORA, amount,
data, isText, isEncrypted, fee, timestamp, reference);
MessageTransactionData messageTransactionData = new MessageTransactionData(timestamp, Group.DEFAULT_GROUP, reference, sender.getPublicKey(), version,
recipient.getAddress(), Asset.QORA, amount, data, isText, isEncrypted, fee);
Transaction messageTransaction = new MessageTransaction(repository, messageTransactionData);
messageTransaction.sign(sender);