qortal/src/qora/transaction/CancelOrderTransaction.java
catbref 9897981de1 Work on assets/payments
* Created PaymentData transfer objects for (recipient, assetId, amount) tuples
* Created corresponding Payment class for validating, processing and orphaning payment(s)

* Modified OrderData to support isClosed for when an Order is cancelled so no more trades can occur

* Migrated CancelOrderTransactions and MultiPaymentTransactions

* Converted MessageTransactions, PaymentTransactions and TransferAssetTransactions to use new Payment class

Can't use PaymentTransformer in PaymentTransformer or TransferAssetTransformer due to serialization differences.
2018-06-14 16:46:55 +01:00

114 lines
4.4 KiB
Java

package qora.transaction;
import java.math.BigDecimal;
import java.util.Arrays;
import data.assets.OrderData;
import data.transaction.CancelOrderTransactionData;
import data.transaction.TransactionData;
import qora.account.Account;
import qora.account.PublicKeyAccount;
import qora.assets.Asset;
import qora.assets.Order;
import qora.crypto.Crypto;
import repository.AssetRepository;
import repository.DataException;
import repository.Repository;
public class CancelOrderTransaction extends Transaction {
// Constructors
public CancelOrderTransaction(Repository repository, TransactionData transactionData) {
super(repository, transactionData);
}
// Processing
@Override
public ValidationResult isValid() throws DataException {
CancelOrderTransactionData cancelOrderTransactionData = (CancelOrderTransactionData) this.transactionData;
AssetRepository assetRepository = this.repository.getAssetRepository();
// Check fee is positive
if (cancelOrderTransactionData.getFee().compareTo(BigDecimal.ZERO) <= 0)
return ValidationResult.NEGATIVE_FEE;
// Check order even exists
OrderData orderData = assetRepository.fromOrderId(cancelOrderTransactionData.getOrderId());
if (orderData == null)
return ValidationResult.ORDER_DOES_NOT_EXIST;
Account creator = new PublicKeyAccount(this.repository, cancelOrderTransactionData.getCreatorPublicKey());
// Check creator's public key results in valid address
if (!Crypto.isValidAddress(creator.getAddress()))
return ValidationResult.INVALID_ADDRESS;
// Check creator's public key matches order's creator's public key
Account orderCreator = new PublicKeyAccount(this.repository, orderData.getCreatorPublicKey());
if (!orderCreator.getAddress().equals(creator.getAddress()))
return ValidationResult.INVALID_ORDER_CREATOR;
// Check creator has enough QORA for fee
if (creator.getConfirmedBalance(Asset.QORA).compareTo(cancelOrderTransactionData.getFee()) == -1)
return ValidationResult.NO_BALANCE;
// Check reference is correct
if (!Arrays.equals(creator.getLastReference(), cancelOrderTransactionData.getReference()))
return ValidationResult.INVALID_REFERENCE;
return ValidationResult.OK;
}
// PROCESS/ORPHAN
@Override
public void process() throws DataException {
CancelOrderTransactionData cancelOrderTransactionData = (CancelOrderTransactionData) this.transactionData;
Account creator = new PublicKeyAccount(this.repository, cancelOrderTransactionData.getCreatorPublicKey());
// Save this transaction itself
this.repository.getTransactionRepository().save(this.transactionData);
// Update creator's balance regarding fee
creator.setConfirmedBalance(Asset.QORA, creator.getConfirmedBalance(Asset.QORA).subtract(cancelOrderTransactionData.getFee()));
// Update creator's last reference
creator.setLastReference(cancelOrderTransactionData.getSignature());
// Mark Order as completed so no more trades can happen
OrderData orderData = this.repository.getAssetRepository().fromOrderId(cancelOrderTransactionData.getOrderId());
Order order = new Order(this.repository, orderData);
order.cancel();
// Update creator's balance with unfulfilled amount
creator.setConfirmedBalance(orderData.getHaveAssetId(), creator.getConfirmedBalance(orderData.getHaveAssetId()).add(order.getAmountLeft()));
}
@Override
public void orphan() throws DataException {
CancelOrderTransactionData cancelOrderTransactionData = (CancelOrderTransactionData) this.transactionData;
Account creator = new PublicKeyAccount(this.repository, cancelOrderTransactionData.getCreatorPublicKey());
// Save this transaction itself
this.repository.getTransactionRepository().delete(this.transactionData);
// Update creator's balance regarding fee
creator.setConfirmedBalance(Asset.QORA, creator.getConfirmedBalance(Asset.QORA).add(cancelOrderTransactionData.getFee()));
// Update creator's last reference
creator.setLastReference(cancelOrderTransactionData.getReference());
// Unmark Order as completed so trades can happen again
OrderData orderData = this.repository.getAssetRepository().fromOrderId(cancelOrderTransactionData.getOrderId());
Order order = new Order(this.repository, orderData);
order.reopen();
// Update creator's balance with unfulfilled amount
creator.setConfirmedBalance(orderData.getHaveAssetId(), creator.getConfirmedBalance(orderData.getHaveAssetId()).subtract(order.getAmountLeft()));
}
}