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