forked from Qortal/qortal
Fixed issue with CancelSellName transactions.
This commit is contained in:
parent
6ad0989ea2
commit
ae44065d7e
@ -3,6 +3,7 @@ package org.qortal.data.transaction;
|
|||||||
import javax.xml.bind.Unmarshaller;
|
import javax.xml.bind.Unmarshaller;
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlTransient;
|
||||||
|
|
||||||
import org.qortal.transaction.Transaction.TransactionType;
|
import org.qortal.transaction.Transaction.TransactionType;
|
||||||
|
|
||||||
@ -19,6 +20,11 @@ public class CancelSellNameTransactionData extends TransactionData {
|
|||||||
@Schema(description = "which name to cancel selling", example = "my-name")
|
@Schema(description = "which name to cancel selling", example = "my-name")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
// For internal use when orphaning
|
||||||
|
@XmlTransient
|
||||||
|
@Schema(hidden = true)
|
||||||
|
private Long salePrice;
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
// For JAXB
|
// For JAXB
|
||||||
@ -30,11 +36,17 @@ public class CancelSellNameTransactionData extends TransactionData {
|
|||||||
this.creatorPublicKey = this.ownerPublicKey;
|
this.creatorPublicKey = this.ownerPublicKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CancelSellNameTransactionData(BaseTransactionData baseTransactionData, String name) {
|
public CancelSellNameTransactionData(BaseTransactionData baseTransactionData, String name, Long salePrice) {
|
||||||
super(TransactionType.CANCEL_SELL_NAME, baseTransactionData);
|
super(TransactionType.CANCEL_SELL_NAME, baseTransactionData);
|
||||||
|
|
||||||
this.ownerPublicKey = baseTransactionData.creatorPublicKey;
|
this.ownerPublicKey = baseTransactionData.creatorPublicKey;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.salePrice = salePrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** From network/API */
|
||||||
|
public CancelSellNameTransactionData(BaseTransactionData baseTransactionData, String name) {
|
||||||
|
this(baseTransactionData, name, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters / setters
|
// Getters / setters
|
||||||
@ -47,4 +59,12 @@ public class CancelSellNameTransactionData extends TransactionData {
|
|||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getSalePrice() {
|
||||||
|
return this.salePrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSalePrice(Long salePrice) {
|
||||||
|
this.salePrice = salePrice;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -180,8 +180,12 @@ public class Name {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void cancelSell(CancelSellNameTransactionData cancelSellNameTransactionData) throws DataException {
|
public void cancelSell(CancelSellNameTransactionData cancelSellNameTransactionData) throws DataException {
|
||||||
// Mark not for-sale but leave price in case we want to orphan
|
// Update previous sale price in transaction data
|
||||||
|
cancelSellNameTransactionData.setSalePrice(this.nameData.getSalePrice());
|
||||||
|
|
||||||
|
// Mark not for-sale
|
||||||
this.nameData.setIsForSale(false);
|
this.nameData.setIsForSale(false);
|
||||||
|
this.nameData.setSalePrice(null);
|
||||||
|
|
||||||
// Save sale info into repository
|
// Save sale info into repository
|
||||||
this.repository.getNameRepository().save(this.nameData);
|
this.repository.getNameRepository().save(this.nameData);
|
||||||
@ -190,6 +194,7 @@ public class Name {
|
|||||||
public void uncancelSell(CancelSellNameTransactionData cancelSellNameTransactionData) throws DataException {
|
public void uncancelSell(CancelSellNameTransactionData cancelSellNameTransactionData) throws DataException {
|
||||||
// Mark as for-sale using existing price
|
// Mark as for-sale using existing price
|
||||||
this.nameData.setIsForSale(true);
|
this.nameData.setIsForSale(true);
|
||||||
|
this.nameData.setSalePrice(cancelSellNameTransactionData.getSalePrice());
|
||||||
|
|
||||||
// Save no-sale info into repository
|
// Save no-sale info into repository
|
||||||
this.repository.getNameRepository().save(this.nameData);
|
this.repository.getNameRepository().save(this.nameData);
|
||||||
|
@ -988,6 +988,11 @@ public class HSQLDBDatabaseUpdates {
|
|||||||
stmt.execute("CREATE INDEX ChatTransactionsChatReferenceIndex ON ChatTransactions (chat_reference)");
|
stmt.execute("CREATE INDEX ChatTransactionsChatReferenceIndex ON ChatTransactions (chat_reference)");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 46:
|
||||||
|
// We need to track the sale price when canceling a name sale, so it can be put back when orphaned
|
||||||
|
stmt.execute("ALTER TABLE CancelSellNameTransactions ADD sale_price QortalAmount");
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// nothing to do
|
// nothing to do
|
||||||
return false;
|
return false;
|
||||||
|
@ -17,15 +17,16 @@ public class HSQLDBCancelSellNameTransactionRepository extends HSQLDBTransaction
|
|||||||
}
|
}
|
||||||
|
|
||||||
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
|
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
|
||||||
String sql = "SELECT name FROM CancelSellNameTransactions WHERE signature = ?";
|
String sql = "SELECT name, sale_price FROM CancelSellNameTransactions WHERE signature = ?";
|
||||||
|
|
||||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
|
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
|
||||||
if (resultSet == null)
|
if (resultSet == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
String name = resultSet.getString(1);
|
String name = resultSet.getString(1);
|
||||||
|
Long salePrice = resultSet.getLong(2);
|
||||||
|
|
||||||
return new CancelSellNameTransactionData(baseTransactionData, name);
|
return new CancelSellNameTransactionData(baseTransactionData, name, salePrice);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DataException("Unable to fetch cancel sell name transaction from repository", e);
|
throw new DataException("Unable to fetch cancel sell name transaction from repository", e);
|
||||||
}
|
}
|
||||||
@ -38,7 +39,7 @@ public class HSQLDBCancelSellNameTransactionRepository extends HSQLDBTransaction
|
|||||||
HSQLDBSaver saveHelper = new HSQLDBSaver("CancelSellNameTransactions");
|
HSQLDBSaver saveHelper = new HSQLDBSaver("CancelSellNameTransactions");
|
||||||
|
|
||||||
saveHelper.bind("signature", cancelSellNameTransactionData.getSignature()).bind("owner", cancelSellNameTransactionData.getOwnerPublicKey()).bind("name",
|
saveHelper.bind("signature", cancelSellNameTransactionData.getSignature()).bind("owner", cancelSellNameTransactionData.getOwnerPublicKey()).bind("name",
|
||||||
cancelSellNameTransactionData.getName());
|
cancelSellNameTransactionData.getName()).bind("sale_price", cancelSellNameTransactionData.getSalePrice());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
saveHelper.execute(this.repository);
|
saveHelper.execute(this.repository);
|
||||||
|
@ -165,6 +165,52 @@ public class BuySellTests extends Common {
|
|||||||
assertEquals("price incorrect", price, nameData.getSalePrice());
|
assertEquals("price incorrect", price, nameData.getSalePrice());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCancelSellNameAndRelist() throws DataException {
|
||||||
|
// Register-name and sell-name
|
||||||
|
testSellName();
|
||||||
|
|
||||||
|
// Cancel Sell-name
|
||||||
|
CancelSellNameTransactionData transactionData = new CancelSellNameTransactionData(TestTransaction.generateBase(alice), name);
|
||||||
|
TransactionUtils.signAndMint(repository, transactionData, alice);
|
||||||
|
|
||||||
|
NameData nameData;
|
||||||
|
|
||||||
|
// Check name is no longer for sale
|
||||||
|
nameData = repository.getNameRepository().fromName(name);
|
||||||
|
assertFalse(nameData.isForSale());
|
||||||
|
assertNull(nameData.getSalePrice());
|
||||||
|
|
||||||
|
// Re-sell-name
|
||||||
|
Long newPrice = random.nextInt(1000) * Amounts.MULTIPLIER;
|
||||||
|
SellNameTransactionData sellNameTransactionData = new SellNameTransactionData(TestTransaction.generateBase(alice), name, newPrice);
|
||||||
|
TransactionUtils.signAndMint(repository, sellNameTransactionData, alice);
|
||||||
|
|
||||||
|
// Check name is for sale
|
||||||
|
nameData = repository.getNameRepository().fromName(name);
|
||||||
|
assertTrue(nameData.isForSale());
|
||||||
|
assertEquals("price incorrect", newPrice, nameData.getSalePrice());
|
||||||
|
|
||||||
|
// Orphan sell-name
|
||||||
|
BlockUtils.orphanLastBlock(repository);
|
||||||
|
|
||||||
|
// Check name no longer for sale
|
||||||
|
nameData = repository.getNameRepository().fromName(name);
|
||||||
|
assertFalse(nameData.isForSale());
|
||||||
|
assertNull(nameData.getSalePrice());
|
||||||
|
|
||||||
|
// Orphan cancel-sell-name
|
||||||
|
BlockUtils.orphanLastBlock(repository);
|
||||||
|
|
||||||
|
// Check name is for sale (at original price)
|
||||||
|
nameData = repository.getNameRepository().fromName(name);
|
||||||
|
assertTrue(nameData.isForSale());
|
||||||
|
assertEquals("price incorrect", price, nameData.getSalePrice());
|
||||||
|
|
||||||
|
// Orphan sell-name and register-name
|
||||||
|
BlockUtils.orphanBlocks(repository, 2);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBuyName() throws DataException {
|
public void testBuyName() throws DataException {
|
||||||
// Register-name and sell-name
|
// Register-name and sell-name
|
||||||
|
Loading…
x
Reference in New Issue
Block a user