Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/java/org/qortal/controller/tradebot/TradeBot.java
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public ResponseResult startResponse(Repository repository, ATData atData, ACCT a
}

// Check Alice doesn't already have an existing, on-going trade-bot entry for this AT.
if (repository.getCrossChainRepository().existsTradeWithAtExcludingStates(atData.getATAddress(), acctTradeBot.getEndStates()))
if (repository.getCrossChainRepository().existsAliceTradeWithAtExcludingStates(atData.getATAddress(), acctTradeBot.getEndStates()))
return ResponseResult.TRADE_ALREADY_EXISTS;

return acctTradeBot.startResponse(repository, atData, acct, crossChainTradeData, foreignKey, receivingAddress);
Expand Down Expand Up @@ -253,7 +253,7 @@ public ResponseResult startResponseMultiple(

for( CrossChainTradeData tradeData : crossChainTradeDataList) {
// Check Alice doesn't already have an existing, on-going trade-bot entry for this AT.
if (repository.getCrossChainRepository().existsTradeWithAtExcludingStates(tradeData.qortalAtAddress, acctTradeBot.getEndStates()))
if (repository.getCrossChainRepository().existsAliceTradeWithAtExcludingStates(tradeData.qortalAtAddress, acctTradeBot.getEndStates()))
return ResponseResult.TRADE_ALREADY_EXISTS;
}
return TradeBotUtils.startResponseMultiple(repository, acct, crossChainTradeDataList, receiveAddress, foreignKey, bitcoiny);
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/qortal/repository/CrossChainRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ public interface CrossChainRepository {
/** Returns true if there is an existing trade-bot entry relating to given AT address, excluding trade-bot entries with given states. */
public boolean existsTradeWithAtExcludingStates(String atAddress, List<String> excludeStates) throws DataException;

/** Returns true if there is an existing Alice-side trade-bot entry relating to given AT address, excluding trade-bot entries with given states. */
public boolean existsAliceTradeWithAtExcludingStates(String atAddress, List<String> excludeStates) throws DataException;

public List<TradeBotData> getAllTradeBotData() throws DataException;

public void save(TradeBotData tradeBotData) throws DataException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,37 @@ public boolean existsTradeWithAtExcludingStates(String atAddress, List<String> e
}
}

@Override
public boolean existsAliceTradeWithAtExcludingStates(String atAddress, List<String> excludeStates) throws DataException {
if (excludeStates == null)
excludeStates = Collections.emptyList();

StringBuilder whereClause = new StringBuilder(256);
whereClause.append("at_address = ? AND trade_state LIKE ?");

Object[] bindParams = new Object[2 + excludeStates.size()];
bindParams[0] = atAddress;
bindParams[1] = "ALICE_%";

if (!excludeStates.isEmpty()) {
whereClause.append(" AND trade_state NOT IN (?");
bindParams[2] = excludeStates.get(0);

for (int i = 1; i < excludeStates.size(); ++i) {
whereClause.append(", ?");
bindParams[2 + i] = excludeStates.get(i);
}

whereClause.append(")");
}

try {
return this.repository.exists("TradeBotStates", whereClause.toString(), bindParams);
} catch (SQLException e) {
throw new DataException("Unable to check for trade-bot state in repository", e);
}
}

@Override
public List<TradeBotData> getAllTradeBotData() throws DataException {
String sql = "SELECT trade_private_key, acct_name, trade_state, trade_state_value, "
Expand Down Expand Up @@ -199,4 +230,4 @@ public int delete(byte[] tradePrivateKey) throws DataException {
}
}

}
}
84 changes: 84 additions & 0 deletions src/test/java/org/qortal/test/CrossChainRepositoryTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.qortal.test;

import org.junit.Before;
import org.junit.Test;
import org.qortal.account.PublicKeyAccount;
import org.qortal.controller.tradebot.LitecoinACCTv1TradeBot;
import org.qortal.controller.tradebot.TradeBot;
import org.qortal.crosschain.LitecoinACCTv1;
import org.qortal.crosschain.SupportedBlockchain;
import org.qortal.crypto.Crypto;
import org.qortal.data.crosschain.TradeBotData;
import org.qortal.repository.DataException;
import org.qortal.repository.Repository;
import org.qortal.repository.RepositoryManager;
import org.qortal.test.common.Common;
import org.qortal.utils.NTP;

import java.util.List;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class CrossChainRepositoryTests extends Common {

@Before
public void beforeTest() throws DataException {
Common.useDefaultSettings();
}

@Test
public void testExistsAliceTradeWithAtExcludingStates() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
String atAddress = Crypto.toATAddress(new byte[64]);
List<String> endStates = LitecoinACCTv1TradeBot.getInstance().getEndStates();

TradeBotData bobData = buildTradeBotData(repository, atAddress, LitecoinACCTv1TradeBot.State.BOB_WAITING_FOR_AT_CONFIRM);
repository.getCrossChainRepository().save(bobData);
repository.saveChanges();

assertFalse(repository.getCrossChainRepository().existsAliceTradeWithAtExcludingStates(atAddress, endStates));

TradeBotData aliceData = buildTradeBotData(repository, atAddress, LitecoinACCTv1TradeBot.State.ALICE_WAITING_FOR_AT_LOCK);
repository.getCrossChainRepository().save(aliceData);
repository.saveChanges();

assertTrue(repository.getCrossChainRepository().existsAliceTradeWithAtExcludingStates(atAddress, endStates));

aliceData.setState(LitecoinACCTv1TradeBot.State.ALICE_DONE.name());
aliceData.setStateValue(LitecoinACCTv1TradeBot.State.ALICE_DONE.value);
repository.getCrossChainRepository().save(aliceData);
repository.saveChanges();

assertFalse(repository.getCrossChainRepository().existsAliceTradeWithAtExcludingStates(atAddress, endStates));
}
}

private TradeBotData buildTradeBotData(Repository repository, String atAddress, LitecoinACCTv1TradeBot.State state) {
byte[] tradePrivateKey = TradeBot.generateTradePrivateKey();

byte[] tradeNativePublicKey = TradeBot.deriveTradeNativePublicKey(tradePrivateKey);
byte[] tradeNativePublicKeyHash = Crypto.hash160(tradeNativePublicKey);
String tradeNativeAddress = Crypto.toAddress(tradeNativePublicKey);

byte[] tradeForeignPublicKey = TradeBot.deriveTradeForeignPublicKey(tradePrivateKey);
byte[] tradeForeignPublicKeyHash = Crypto.hash160(tradeForeignPublicKey);

byte[] creatorPublicKey = new byte[32];
PublicKeyAccount creator = new PublicKeyAccount(repository, creatorPublicKey);

long timestamp = NTP.getTime();
long foreignAmount = 1234L;
long qortAmount = 5678L;
byte[] receivingAccountInfo = new byte[20];

return new TradeBotData(tradePrivateKey, LitecoinACCTv1.NAME,
state.name(), state.value,
creator.getAddress(), atAddress, timestamp, qortAmount,
tradeNativePublicKey, tradeNativePublicKeyHash, tradeNativeAddress,
null, null,
SupportedBlockchain.LITECOIN.name(),
tradeForeignPublicKey, tradeForeignPublicKeyHash,
foreignAmount, null, null, null, receivingAccountInfo);
}
}
Loading