mirror of
https://github.com/Qortal/qortal.git
synced 2025-02-11 09:45:50 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
950c4a5b35
@ -52,6 +52,8 @@ import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
|
||||
@Path("/crosschain")
|
||||
@Tag(name = "Cross-Chain")
|
||||
public class CrossChainResource {
|
||||
@ -255,6 +257,12 @@ public class CrossChainResource {
|
||||
description = "Only return trades that completed on/after this timestamp (milliseconds since epoch)",
|
||||
example = "1597310000000"
|
||||
) @QueryParam("minimumTimestamp") Long minimumTimestamp,
|
||||
@Parameter(
|
||||
description = "Optionally filter by buyer Qortal address"
|
||||
) @QueryParam("buyerAddress") String buyerAddress,
|
||||
@Parameter(
|
||||
description = "Optionally filter by seller Qortal address"
|
||||
) @QueryParam("sellerAddress") String sellerAddress,
|
||||
@Parameter( ref = "limit") @QueryParam("limit") Integer limit,
|
||||
@Parameter( ref = "offset" ) @QueryParam("offset") Integer offset,
|
||||
@Parameter( ref = "reverse" ) @QueryParam("reverse") Boolean reverse) {
|
||||
@ -296,7 +304,7 @@ public class CrossChainResource {
|
||||
byte[] codeHash = acctInfo.getKey().value;
|
||||
ACCT acct = acctInfo.getValue().get();
|
||||
|
||||
List<ATStateData> atStates = repository.getATRepository().getMatchingFinalATStates(codeHash,
|
||||
List<ATStateData> atStates = repository.getATRepository().getMatchingFinalATStates(codeHash, buyerAddress, sellerAddress,
|
||||
isFinished, acct.getModeByteOffset(), (long) AcctMode.REDEEMED.value, minimumFinalHeight,
|
||||
limit, offset, reverse);
|
||||
|
||||
|
@ -98,7 +98,7 @@ public class TradeOffersWebSocket extends ApiWebSocket implements Listener {
|
||||
byte[] codeHash = acctInfo.getKey().value;
|
||||
ACCT acct = acctInfo.getValue().get();
|
||||
|
||||
List<ATStateData> atStates = repository.getATRepository().getMatchingFinalATStates(codeHash,
|
||||
List<ATStateData> atStates = repository.getATRepository().getMatchingFinalATStates(codeHash, null, null,
|
||||
isFinished, dataByteOffset, expectedValue, minimumFinalHeight,
|
||||
null, null, null);
|
||||
|
||||
@ -259,7 +259,7 @@ public class TradeOffersWebSocket extends ApiWebSocket implements Listener {
|
||||
ACCT acct = acctInfo.getValue().get();
|
||||
|
||||
Integer dataByteOffset = acct.getModeByteOffset();
|
||||
List<ATStateData> initialAtStates = repository.getATRepository().getMatchingFinalATStates(codeHash,
|
||||
List<ATStateData> initialAtStates = repository.getATRepository().getMatchingFinalATStates(codeHash, null, null,
|
||||
isFinished, dataByteOffset, expectedValue, minimumFinalHeight,
|
||||
null, null, null);
|
||||
|
||||
@ -298,7 +298,7 @@ public class TradeOffersWebSocket extends ApiWebSocket implements Listener {
|
||||
byte[] codeHash = acctInfo.getKey().value;
|
||||
ACCT acct = acctInfo.getValue().get();
|
||||
|
||||
List<ATStateData> historicAtStates = repository.getATRepository().getMatchingFinalATStates(codeHash,
|
||||
List<ATStateData> historicAtStates = repository.getATRepository().getMatchingFinalATStates(codeHash, null, null,
|
||||
isFinished, dataByteOffset, expectedValue, minimumFinalHeight,
|
||||
null, null, null);
|
||||
|
||||
|
@ -76,7 +76,7 @@ public interface ATRepository {
|
||||
* Although <tt>expectedValue</tt>, if provided, is natively an unsigned long,
|
||||
* the data segment comparison is done via unsigned hex string.
|
||||
*/
|
||||
public List<ATStateData> getMatchingFinalATStates(byte[] codeHash, Boolean isFinished,
|
||||
public List<ATStateData> getMatchingFinalATStates(byte[] codeHash, String buyerAddress, String sellerAddress, Boolean isFinished,
|
||||
Integer dataByteOffset, Long expectedValue, Integer minimumFinalHeight,
|
||||
Integer limit, Integer offset, Boolean reverse) throws DataException;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.qortal.repository.hsqldb;
|
||||
|
||||
import com.google.common.primitives.Longs;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.qortal.controller.Controller;
|
||||
@ -16,6 +17,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.qortal.data.account.AccountData;
|
||||
|
||||
public class HSQLDBATRepository implements ATRepository {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(HSQLDBATRepository.class);
|
||||
@ -400,7 +403,7 @@ public class HSQLDBATRepository implements ATRepository {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ATStateData> getMatchingFinalATStates(byte[] codeHash, Boolean isFinished,
|
||||
public List<ATStateData> getMatchingFinalATStates(byte[] codeHash, String buyerAddress, String sellerAddress, Boolean isFinished,
|
||||
Integer dataByteOffset, Long expectedValue, Integer minimumFinalHeight,
|
||||
Integer limit, Integer offset, Boolean reverse) throws DataException {
|
||||
StringBuilder sql = new StringBuilder(1024);
|
||||
@ -421,10 +424,14 @@ public class HSQLDBATRepository implements ATRepository {
|
||||
|
||||
// Order by AT_address and height to use compound primary key as index
|
||||
// Both must be the same direction (DESC) also
|
||||
sql.append("ORDER BY ATStates.AT_address DESC, ATStates.height DESC "
|
||||
+ "LIMIT 1 "
|
||||
+ ") AS FinalATStates "
|
||||
+ "WHERE code_hash = ? ");
|
||||
sql.append("ORDER BY ATStates.height DESC LIMIT 1) AS FinalATStates ");
|
||||
|
||||
// Optional LEFT JOIN with ATTRANSACTIONS for buyerAddress
|
||||
if (buyerAddress != null && !buyerAddress.isEmpty()) {
|
||||
sql.append("LEFT JOIN ATTRANSACTIONS tx ON tx.at_address = ATs.AT_address ");
|
||||
}
|
||||
|
||||
sql.append("WHERE ATs.code_hash = ? ");
|
||||
bindParams.add(codeHash);
|
||||
|
||||
if (isFinished != null) {
|
||||
@ -443,6 +450,20 @@ public class HSQLDBATRepository implements ATRepository {
|
||||
bindParams.add(rawExpectedValue);
|
||||
}
|
||||
|
||||
if (buyerAddress != null && !buyerAddress.isEmpty()) {
|
||||
sql.append("AND tx.recipient = ? ");
|
||||
bindParams.add(buyerAddress);
|
||||
}
|
||||
|
||||
|
||||
if (sellerAddress != null && !sellerAddress.isEmpty()) {
|
||||
// Convert sellerAddress to publicKey (method depends on your implementation)
|
||||
AccountData accountData = this.repository.getAccountRepository().getAccount(sellerAddress);
|
||||
byte[] publicKey = accountData.getPublicKey();
|
||||
sql.append("AND ATs.creator = ? ");
|
||||
bindParams.add(publicKey);
|
||||
}
|
||||
|
||||
sql.append(" ORDER BY FinalATStates.height ");
|
||||
if (reverse != null && reverse)
|
||||
sql.append("DESC");
|
||||
@ -483,7 +504,7 @@ public class HSQLDBATRepository implements ATRepository {
|
||||
Integer dataByteOffset, Long expectedValue,
|
||||
int minimumCount, int maximumCount, long minimumPeriod) throws DataException {
|
||||
// We need most recent entry first so we can use its timestamp to slice further results
|
||||
List<ATStateData> mostRecentStates = this.getMatchingFinalATStates(codeHash, isFinished,
|
||||
List<ATStateData> mostRecentStates = this.getMatchingFinalATStates(codeHash, null, null, isFinished,
|
||||
dataByteOffset, expectedValue, null,
|
||||
1, 0, true);
|
||||
|
||||
|
@ -20,17 +20,21 @@
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
z-index: 1000;
|
||||
top: 45%;
|
||||
top: 50%;
|
||||
-ms-transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
transform: translate(-50% , -50%);
|
||||
left: 50%;
|
||||
}
|
||||
#panel {
|
||||
text-align: center;
|
||||
background: white;
|
||||
word-wrap: break-word;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
margin: auto;
|
||||
padding: 25px;
|
||||
border-radius: 30px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#status {
|
||||
color: #03a9f4;
|
||||
|
@ -405,7 +405,7 @@ public class RepositoryTests extends Common {
|
||||
Integer offset = null;
|
||||
Boolean reverse = null;
|
||||
|
||||
hsqldb.getATRepository().getMatchingFinalATStates(codeHash, isFinished, dataByteOffset, expectedValue, minimumFinalHeight, limit, offset, reverse);
|
||||
hsqldb.getATRepository().getMatchingFinalATStates(codeHash,null, null, isFinished, dataByteOffset, expectedValue, minimumFinalHeight, limit, offset, reverse);
|
||||
} catch (DataException e) {
|
||||
fail("HSQLDB bug #1580");
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class CrossChainApiTests extends ApiCommon {
|
||||
@Test
|
||||
public void testGetCompletedTrades() {
|
||||
long minimumTimestamp = System.currentTimeMillis();
|
||||
assertNoApiError((limit, offset, reverse) -> this.crossChainResource.getCompletedTrades(SPECIFIC_BLOCKCHAIN, minimumTimestamp, limit, offset, reverse));
|
||||
assertNoApiError((limit, offset, reverse) -> this.crossChainResource.getCompletedTrades(SPECIFIC_BLOCKCHAIN, minimumTimestamp, null, null, limit, offset, reverse));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -35,8 +35,8 @@ public class CrossChainApiTests extends ApiCommon {
|
||||
Integer offset = null;
|
||||
Boolean reverse = null;
|
||||
|
||||
assertApiError(ApiError.INVALID_CRITERIA, () -> this.crossChainResource.getCompletedTrades(SPECIFIC_BLOCKCHAIN, -1L /*minimumTimestamp*/, limit, offset, reverse));
|
||||
assertApiError(ApiError.INVALID_CRITERIA, () -> this.crossChainResource.getCompletedTrades(SPECIFIC_BLOCKCHAIN, 0L /*minimumTimestamp*/, limit, offset, reverse));
|
||||
assertApiError(ApiError.INVALID_CRITERIA, () -> this.crossChainResource.getCompletedTrades(SPECIFIC_BLOCKCHAIN, -1L /*minimumTimestamp*/, null, null, limit, offset, reverse));
|
||||
assertApiError(ApiError.INVALID_CRITERIA, () -> this.crossChainResource.getCompletedTrades(SPECIFIC_BLOCKCHAIN, 0L /*minimumTimestamp*/, null, null, limit, offset, reverse));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -218,6 +218,8 @@ public class AtRepositoryTests extends Common {
|
||||
|
||||
List<ATStateData> atStates = repository.getATRepository().getMatchingFinalATStates(
|
||||
codeHash,
|
||||
null,
|
||||
null,
|
||||
isFinished,
|
||||
dataByteOffset,
|
||||
expectedValue,
|
||||
@ -264,6 +266,8 @@ public class AtRepositoryTests extends Common {
|
||||
|
||||
List<ATStateData> atStates = repository.getATRepository().getMatchingFinalATStates(
|
||||
codeHash,
|
||||
null,
|
||||
null,
|
||||
isFinished,
|
||||
dataByteOffset,
|
||||
expectedValue,
|
||||
|
Loading…
x
Reference in New Issue
Block a user