diff --git a/src/main/java/org/qortal/crosschain/BTCACCT.java b/src/main/java/org/qortal/crosschain/BTCACCT.java
index 404c9fb0..1adacfb8 100644
--- a/src/main/java/org/qortal/crosschain/BTCACCT.java
+++ b/src/main/java/org/qortal/crosschain/BTCACCT.java
@@ -105,7 +105,7 @@ public class BTCACCT {
public static final int SECRET_LENGTH = 32;
public static final int MIN_LOCKTIME = 1500000000;
- public static final byte[] CODE_BYTES_HASH = HashCode.fromString("a472f32a6799ff85ed99567701b42fa228c58a09d38485ab208ad78d0f2cc813").asBytes(); // SHA256 of AT code bytes
+ public static final byte[] CODE_BYTES_HASH = HashCode.fromString("f7f419522a9aaa3c671149878f8c1374dfc59d4fd86ca43ff2a4d913cfbc9e89").asBytes(); // SHA256 of AT code bytes
/** Value offset into AT segment where 'mode' variable (long) is stored. (Multiply by MachineState.VALUE_SIZE for byte offset). */
private static final int MODE_VALUE_OFFSET = 68;
@@ -343,7 +343,8 @@ public class BTCACCT {
Integer labelTradeTxnLoop = null;
Integer labelCheckTradeTxn = null;
-
+ Integer labelCheckCancelTxn = null;
+ Integer labelNotTradeNorCancelTxn = null;
Integer labelCheckNonRefundTradeTxn = null;
Integer labelTradeTxnExtract = null;
Integer labelRedeemTxnLoop = null;
@@ -395,38 +396,43 @@ public class BTCACCT {
// If transaction type is not MESSAGE type then go look for another transaction
codeByteBuffer.put(OpCode.BNE_DAT.compile(addrTxnType, addrMessageTxnType, calcOffset(codeByteBuffer, labelTradeTxnLoop)));
- /* Check transaction's sender. We're expecting AT creator's trade address. */
+ /* Check transaction's sender. We're expecting AT creator's trade address for 'trade' message, or AT creator's own address for 'cancel' message. */
// Extract sender address from transaction into B register
codeByteBuffer.put(OpCode.EXT_FUN.compile(FunctionCode.PUT_ADDRESS_FROM_TX_IN_A_INTO_B));
// Save B register into data segment starting at addrMessageSender1 (as pointed to by addrMessageSenderPointer)
codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrMessageSenderPointer));
- // Compare each part of transaction's sender's address with expected address. If they don't match, look for another transaction.
- codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender1, addrCreatorTradeAddress1, calcOffset(codeByteBuffer, labelTradeTxnLoop)));
- codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender2, addrCreatorTradeAddress2, calcOffset(codeByteBuffer, labelTradeTxnLoop)));
- codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender3, addrCreatorTradeAddress3, calcOffset(codeByteBuffer, labelTradeTxnLoop)));
- codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender4, addrCreatorTradeAddress4, calcOffset(codeByteBuffer, labelTradeTxnLoop)));
+ // Compare each part of message sender's address with AT creator's trade address. If they don't match, check for cancel situation.
+ codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender1, addrCreatorTradeAddress1, calcOffset(codeByteBuffer, labelCheckCancelTxn)));
+ codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender2, addrCreatorTradeAddress2, calcOffset(codeByteBuffer, labelCheckCancelTxn)));
+ codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender3, addrCreatorTradeAddress3, calcOffset(codeByteBuffer, labelCheckCancelTxn)));
+ codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender4, addrCreatorTradeAddress4, calcOffset(codeByteBuffer, labelCheckCancelTxn)));
+ // Message sender's address matches AT creator's trade address so go process 'trade' message
+ codeByteBuffer.put(OpCode.JMP_ADR.compile(labelCheckNonRefundTradeTxn == null ? 0 : labelCheckNonRefundTradeTxn));
- /* Extract trade partner info from message */
+ /* Checking message sender for possible cancel message */
+ labelCheckCancelTxn = codeByteBuffer.position();
- // Extract message from transaction into B register
- codeByteBuffer.put(OpCode.EXT_FUN.compile(FunctionCode.PUT_MESSAGE_FROM_TX_IN_A_INTO_B));
- // Save B register into data segment starting at addrQortalPartnerAddress1 (as pointed to by addrQortalPartnerAddressPointer)
- codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrQortalPartnerAddressPointer));
- // Compare each of partner address with creator's address (for offer-cancel scenario). If they don't match, assume address is trade partner.
- codeByteBuffer.put(OpCode.BNE_DAT.compile(addrQortalPartnerAddress1, addrCreatorAddress1, calcOffset(codeByteBuffer, labelCheckNonRefundTradeTxn)));
- codeByteBuffer.put(OpCode.BNE_DAT.compile(addrQortalPartnerAddress2, addrCreatorAddress2, calcOffset(codeByteBuffer, labelCheckNonRefundTradeTxn)));
- codeByteBuffer.put(OpCode.BNE_DAT.compile(addrQortalPartnerAddress3, addrCreatorAddress3, calcOffset(codeByteBuffer, labelCheckNonRefundTradeTxn)));
- codeByteBuffer.put(OpCode.BNE_DAT.compile(addrQortalPartnerAddress4, addrCreatorAddress4, calcOffset(codeByteBuffer, labelCheckNonRefundTradeTxn)));
+ // Compare each part of message sender's address with AT creator's address. If they don't match, look for another transaction.
+ codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender1, addrCreatorAddress1, calcOffset(codeByteBuffer, labelNotTradeNorCancelTxn)));
+ codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender2, addrCreatorAddress2, calcOffset(codeByteBuffer, labelNotTradeNorCancelTxn)));
+ codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender3, addrCreatorAddress3, calcOffset(codeByteBuffer, labelNotTradeNorCancelTxn)));
+ codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender4, addrCreatorAddress4, calcOffset(codeByteBuffer, labelNotTradeNorCancelTxn)));
// Partner address is AT creator's address, so cancel offer and finish.
codeByteBuffer.put(OpCode.SET_VAL.compile(addrMode, Mode.CANCELLED.value));
// We're finished forever (finishing auto-refunds remaining balance to AT creator)
codeByteBuffer.put(OpCode.FIN_IMD.compile());
+ /* Not trade nor cancel message */
+ labelNotTradeNorCancelTxn = codeByteBuffer.position();
+
+ // Loop to find another transaction
+ codeByteBuffer.put(OpCode.JMP_ADR.compile(labelTradeTxnLoop == null ? 0 : labelTradeTxnLoop));
+
/* Possible switch-to-trade-mode message */
labelCheckNonRefundTradeTxn = codeByteBuffer.position();
- // Not offer-cancel scenario so check we received expected number of message bytes
+ // Check 'trade' message we received has expected number of message bytes
codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(QortalFunctionCode.GET_MESSAGE_LENGTH_FROM_TX_IN_A.value, addrMessageLength));
// If message length matches, branch to info extraction code
codeByteBuffer.put(OpCode.BEQ_DAT.compile(addrMessageLength, addrExpectedTradeMessageLength, calcOffset(codeByteBuffer, labelTradeTxnExtract)));
@@ -436,9 +442,13 @@ public class BTCACCT {
/* Extracting info from 'trade' MESSAGE transaction */
labelTradeTxnExtract = codeByteBuffer.position();
- // Message is expected length, grab next 32 bytes
- codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(QortalFunctionCode.PUT_PARTIAL_MESSAGE_FROM_TX_IN_A_INTO_B.value, addrTradeMessagePartnerBitcoinPKHOffset));
+ // Extract message from transaction into B register
+ codeByteBuffer.put(OpCode.EXT_FUN.compile(FunctionCode.PUT_MESSAGE_FROM_TX_IN_A_INTO_B));
+ // Save B register into data segment starting at addrQortalPartnerAddress1 (as pointed to by addrQortalPartnerAddressPointer)
+ codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrQortalPartnerAddressPointer));
+ // Extract trade partner's Bitcoin public key hash (PKH)
+ codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(QortalFunctionCode.PUT_PARTIAL_MESSAGE_FROM_TX_IN_A_INTO_B.value, addrTradeMessagePartnerBitcoinPKHOffset));
// Extract partner's Bitcoin PKH (we only really use values from B1-B3)
codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrPartnerBitcoinPKHPointer));
// Also extract lockTimeB
diff --git a/src/test/java/org/qortal/test/btcacct/AtTests.java b/src/test/java/org/qortal/test/btcacct/AtTests.java
index b271075c..fd187938 100644
--- a/src/test/java/org/qortal/test/btcacct/AtTests.java
+++ b/src/test/java/org/qortal/test/btcacct/AtTests.java
@@ -52,7 +52,6 @@ public class AtTests extends Common {
public static final long redeemAmount = 80_40200000L;
public static final long fundingAmount = 123_45600000L;
public static final long bitcoinAmount = 864200L;
- public static final byte[] bitcoinReceivePublicKeyHash = HashCode.fromString("00112233445566778899aabbccddeeff").asBytes();
private static final Random RANDOM = new Random();
@@ -63,9 +62,9 @@ public class AtTests extends Common {
@Test
public void testCompile() {
- Account deployer = Common.getTestAccount(null, "chloe");
+ PrivateKeyAccount tradeAccount = createTradeAccount(null);
- byte[] creationBytes = BTCACCT.buildQortalAT(deployer.getAddress(), bitcoinPublicKeyHash, hashOfSecretB, redeemAmount, bitcoinAmount, tradeTimeout);
+ byte[] creationBytes = BTCACCT.buildQortalAT(tradeAccount.getAddress(), bitcoinPublicKeyHash, hashOfSecretB, redeemAmount, bitcoinAmount, tradeTimeout);
System.out.println("CIYAM AT creation bytes: " + HashCode.fromBytes(creationBytes).toString());
}
@@ -73,12 +72,14 @@ public class AtTests extends Common {
public void testDeploy() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe");
+ PrivateKeyAccount tradeAccount = createTradeAccount(repository);
+
PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert");
long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT);
long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT);
- DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer);
+ DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress());
long expectedBalance = deployersInitialBalance - fundingAmount - deployAtTransaction.getTransactionData().getFee();
long actualBalance = deployer.getConfirmedBalance(Asset.QORT);
@@ -120,12 +121,14 @@ public class AtTests extends Common {
public void testOfferCancel() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe");
+ PrivateKeyAccount tradeAccount = createTradeAccount(repository);
+
PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert");
long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT);
long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT);
- DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer);
+ DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress());
Account at = deployAtTransaction.getATAccount();
String atAddress = at.getAddress();
@@ -140,14 +143,6 @@ public class AtTests extends Common {
// AT should process 'cancel' message in next block
BlockUtils.mintBlock(repository);
- long expectedMinimumBalance = deployersPostDeploymentBalance;
- long expectedMaximumBalance = deployersInitialBalance - deployAtFee - messageFee;
-
- long actualBalance = deployer.getConfirmedBalance(Asset.QORT);
-
- assertTrue(String.format("Deployer's balance %s should be above minimum %s", actualBalance, expectedMinimumBalance), actualBalance > expectedMinimumBalance);
- assertTrue(String.format("Deployer's balance %s should be below maximum %s", actualBalance, expectedMaximumBalance), actualBalance < expectedMaximumBalance);
-
describeAt(repository, atAddress);
// Check AT is finished
@@ -158,9 +153,19 @@ public class AtTests extends Common {
CrossChainTradeData tradeData = BTCACCT.populateTradeData(repository, atData);
assertEquals(BTCACCT.Mode.CANCELLED, tradeData.mode);
+ // Check balances
+ long expectedMinimumBalance = deployersPostDeploymentBalance;
+ long expectedMaximumBalance = deployersInitialBalance - deployAtFee - messageFee;
+
+ long actualBalance = deployer.getConfirmedBalance(Asset.QORT);
+
+ assertTrue(String.format("Deployer's balance %s should be above minimum %s", actualBalance, expectedMinimumBalance), actualBalance > expectedMinimumBalance);
+ assertTrue(String.format("Deployer's balance %s should be below maximum %s", actualBalance, expectedMaximumBalance), actualBalance < expectedMaximumBalance);
+
// Test orphaning
BlockUtils.orphanLastBlock(repository);
+ // Check balances
long expectedBalance = deployersPostDeploymentBalance - messageFee;
actualBalance = deployer.getConfirmedBalance(Asset.QORT);
@@ -173,12 +178,14 @@ public class AtTests extends Common {
public void testOfferCancelInvalidLength() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe");
+ PrivateKeyAccount tradeAccount = createTradeAccount(repository);
+
PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert");
long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT);
long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT);
- DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer);
+ DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress());
Account at = deployAtTransaction.getATAccount();
String atAddress = at.getAddress();
@@ -192,18 +199,18 @@ public class AtTests extends Common {
long messageFee = messageTransaction.getTransactionData().getFee();
// AT should process 'cancel' message in next block
- // As message is too short, it will be padded to 32bytes and (probably) contain incorrect sender to be valid cancel
+ // As message is too short, it will be padded to 32bytes but cancel code doesn't care about message content, so should be ok
BlockUtils.mintBlock(repository);
describeAt(repository, atAddress);
- // Check AT is NOT finished
+ // Check AT is finished
ATData atData = repository.getATRepository().fromATAddress(atAddress);
- assertFalse(atData.getIsFinished());
+ assertTrue(atData.getIsFinished());
- // AT should still be in OFFERING mode
+ // AT should be in CANCELLED mode
CrossChainTradeData tradeData = BTCACCT.populateTradeData(repository, atData);
- assertEquals(BTCACCT.Mode.OFFERING, tradeData.mode);
+ assertEquals(BTCACCT.Mode.CANCELLED, tradeData.mode);
}
}
@@ -212,12 +219,14 @@ public class AtTests extends Common {
public void testTradingInfoProcessing() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe");
+ PrivateKeyAccount tradeAccount = createTradeAccount(repository);
+
PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert");
long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT);
long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT);
- DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer);
+ DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress());
Account at = deployAtTransaction.getATAccount();
String atAddress = at.getAddress();
@@ -227,14 +236,13 @@ public class AtTests extends Common {
// Send trade info to AT
byte[] messageData = BTCACCT.buildTradeMessage(partner.getAddress(), bitcoinPublicKeyHash, hashOfSecretA, lockTimeA, lockTimeB);
- MessageTransaction messageTransaction = sendMessage(repository, deployer, messageData, atAddress);
+ MessageTransaction messageTransaction = sendMessage(repository, tradeAccount, messageData, atAddress);
Block postDeploymentBlock = BlockUtils.mintBlock(repository);
int postDeploymentBlockHeight = postDeploymentBlock.getBlockData().getHeight();
long deployAtFee = deployAtTransaction.getTransactionData().getFee();
- long messageFee = messageTransaction.getTransactionData().getFee();
- long deployersPostDeploymentBalance = deployersInitialBalance - fundingAmount - deployAtFee - messageFee;
+ long deployersPostDeploymentBalance = deployersInitialBalance - fundingAmount - deployAtFee;
describeAt(repository, atAddress);
@@ -256,6 +264,7 @@ public class AtTests extends Common {
// Test orphaning
BlockUtils.orphanToBlock(repository, postDeploymentBlockHeight);
+ // Check balances
long expectedBalance = deployersPostDeploymentBalance;
long actualBalance = deployer.getConfirmedBalance(Asset.QORT);
@@ -269,13 +278,16 @@ public class AtTests extends Common {
public void testIncorrectTradeSender() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe");
+ PrivateKeyAccount tradeAccount = createTradeAccount(repository);
+
PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert");
+
PrivateKeyAccount bystander = Common.getTestAccount(repository, "bob");
long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT);
long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT);
- DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer);
+ DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress());
Account at = deployAtTransaction.getATAccount();
String atAddress = at.getAddress();
@@ -309,12 +321,14 @@ public class AtTests extends Common {
public void testAutomaticTradeRefund() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe");
+ PrivateKeyAccount tradeAccount = createTradeAccount(repository);
+
PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert");
long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT);
long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT);
- DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer);
+ DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress());
Account at = deployAtTransaction.getATAccount();
String atAddress = at.getAddress();
@@ -324,14 +338,14 @@ public class AtTests extends Common {
// Send trade info to AT
byte[] messageData = BTCACCT.buildTradeMessage(partner.getAddress(), bitcoinPublicKeyHash, hashOfSecretA, lockTimeA, lockTimeB);
- MessageTransaction messageTransaction = sendMessage(repository, deployer, messageData, atAddress);
+ MessageTransaction messageTransaction = sendMessage(repository, tradeAccount, messageData, atAddress);
Block postDeploymentBlock = BlockUtils.mintBlock(repository);
int postDeploymentBlockHeight = postDeploymentBlock.getBlockData().getHeight();
+ // Check refund
long deployAtFee = deployAtTransaction.getTransactionData().getFee();
- long messageFee = messageTransaction.getTransactionData().getFee();
- long deployersPostDeploymentBalance = deployersInitialBalance - fundingAmount - deployAtFee - messageFee;
+ long deployersPostDeploymentBalance = deployersInitialBalance - fundingAmount - deployAtFee;
checkTradeRefund(repository, deployer, deployersInitialBalance, deployAtFee);
@@ -348,6 +362,7 @@ public class AtTests extends Common {
// Test orphaning
BlockUtils.orphanToBlock(repository, postDeploymentBlockHeight);
+ // Check balances
long expectedBalance = deployersPostDeploymentBalance;
long actualBalance = deployer.getConfirmedBalance(Asset.QORT);
@@ -360,12 +375,14 @@ public class AtTests extends Common {
public void testCorrectSecretsCorrectSender() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe");
+ PrivateKeyAccount tradeAccount = createTradeAccount(repository);
+
PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert");
long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT);
long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT);
- DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer);
+ DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress());
Account at = deployAtTransaction.getATAccount();
String atAddress = at.getAddress();
@@ -375,7 +392,7 @@ public class AtTests extends Common {
// Send trade info to AT
byte[] messageData = BTCACCT.buildTradeMessage(partner.getAddress(), bitcoinPublicKeyHash, hashOfSecretA, lockTimeA, lockTimeB);
- MessageTransaction messageTransaction = sendMessage(repository, deployer, messageData, atAddress);
+ MessageTransaction messageTransaction = sendMessage(repository, tradeAccount, messageData, atAddress);
// Give AT time to process message
BlockUtils.mintBlock(repository);
@@ -398,6 +415,7 @@ public class AtTests extends Common {
CrossChainTradeData tradeData = BTCACCT.populateTradeData(repository, atData);
assertEquals(BTCACCT.Mode.REDEEMED, tradeData.mode);
+ // Check balances
long expectedBalance = partnersInitialBalance - messageTransaction.getTransactionData().getFee() + redeemAmount;
long actualBalance = partner.getConfirmedBalance(Asset.QORT);
@@ -406,6 +424,7 @@ public class AtTests extends Common {
// Orphan redeem
BlockUtils.orphanLastBlock(repository);
+ // Check balances
expectedBalance = partnersInitialBalance - messageTransaction.getTransactionData().getFee();
actualBalance = partner.getConfirmedBalance(Asset.QORT);
@@ -423,13 +442,16 @@ public class AtTests extends Common {
public void testCorrectSecretsIncorrectSender() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe");
+ PrivateKeyAccount tradeAccount = createTradeAccount(repository);
+
PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert");
+
PrivateKeyAccount bystander = Common.getTestAccount(repository, "bob");
long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT);
long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT);
- DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer);
+ DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress());
long deployAtFee = deployAtTransaction.getTransactionData().getFee();
Account at = deployAtTransaction.getATAccount();
@@ -441,7 +463,7 @@ public class AtTests extends Common {
// Send trade info to AT
byte[] messageData = BTCACCT.buildTradeMessage(partner.getAddress(), bitcoinPublicKeyHash, hashOfSecretA, lockTimeA, lockTimeB);
- MessageTransaction messageTransaction = sendMessage(repository, deployer, messageData, atAddress);
+ MessageTransaction messageTransaction = sendMessage(repository, tradeAccount, messageData, atAddress);
// Give AT time to process message
BlockUtils.mintBlock(repository);
@@ -464,11 +486,13 @@ public class AtTests extends Common {
CrossChainTradeData tradeData = BTCACCT.populateTradeData(repository, atData);
assertEquals(BTCACCT.Mode.TRADING, tradeData.mode);
+ // Check balances
long expectedBalance = partnersInitialBalance;
long actualBalance = partner.getConfirmedBalance(Asset.QORT);
assertEquals("Partner's balance incorrect", expectedBalance, actualBalance);
+ // Check eventual refund
checkTradeRefund(repository, deployer, deployersInitialBalance, deployAtFee);
}
}
@@ -478,12 +502,14 @@ public class AtTests extends Common {
public void testIncorrectSecretsCorrectSender() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe");
+ PrivateKeyAccount tradeAccount = createTradeAccount(repository);
+
PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert");
long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT);
long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT);
- DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer);
+ DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress());
long deployAtFee = deployAtTransaction.getTransactionData().getFee();
Account at = deployAtTransaction.getATAccount();
@@ -495,7 +521,7 @@ public class AtTests extends Common {
// Send trade info to AT
byte[] messageData = BTCACCT.buildTradeMessage(partner.getAddress(), bitcoinPublicKeyHash, hashOfSecretA, lockTimeA, lockTimeB);
- MessageTransaction messageTransaction = sendMessage(repository, deployer, messageData, atAddress);
+ MessageTransaction messageTransaction = sendMessage(repository, tradeAccount, messageData, atAddress);
// Give AT time to process message
BlockUtils.mintBlock(repository);
@@ -542,11 +568,13 @@ public class AtTests extends Common {
tradeData = BTCACCT.populateTradeData(repository, atData);
assertEquals(BTCACCT.Mode.TRADING, tradeData.mode);
+ // Check balances
expectedBalance = partnersInitialBalance - messageTransaction.getTransactionData().getFee() * 2;
actualBalance = partner.getConfirmedBalance(Asset.QORT);
assertEquals("Partner's balance incorrect", expectedBalance, actualBalance);
+ // Check eventual refund
checkTradeRefund(repository, deployer, deployersInitialBalance, deployAtFee);
}
}
@@ -556,12 +584,14 @@ public class AtTests extends Common {
public void testCorrectSecretsCorrectSenderInvalidMessageLength() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe");
+ PrivateKeyAccount tradeAccount = createTradeAccount(repository);
+
PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert");
long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT);
long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT);
- DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer);
+ DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress());
Account at = deployAtTransaction.getATAccount();
String atAddress = at.getAddress();
@@ -571,7 +601,7 @@ public class AtTests extends Common {
// Send trade info to AT
byte[] messageData = BTCACCT.buildTradeMessage(partner.getAddress(), bitcoinPublicKeyHash, hashOfSecretA, lockTimeA, lockTimeB);
- MessageTransaction messageTransaction = sendMessage(repository, deployer, messageData, atAddress);
+ MessageTransaction messageTransaction = sendMessage(repository, tradeAccount, messageData, atAddress);
// Give AT time to process message
BlockUtils.mintBlock(repository);
@@ -601,12 +631,14 @@ public class AtTests extends Common {
public void testDescribeDeployed() throws DataException {
try (final Repository repository = RepositoryManager.getRepository()) {
PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe");
+ PrivateKeyAccount tradeAccount = createTradeAccount(repository);
+
PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert");
long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT);
long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT);
- DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer);
+ DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress());
List executableAts = repository.getATRepository().getAllExecutableATs();
@@ -634,8 +666,8 @@ public class AtTests extends Common {
return (int) (messageTimestamp / 1000L + tradeTimeout * 60);
}
- private DeployAtTransaction doDeploy(Repository repository, PrivateKeyAccount deployer) throws DataException {
- byte[] creationBytes = BTCACCT.buildQortalAT(deployer.getAddress(), bitcoinPublicKeyHash, hashOfSecretB, redeemAmount, bitcoinAmount, tradeTimeout);
+ private DeployAtTransaction doDeploy(Repository repository, PrivateKeyAccount deployer, String tradeAddress) throws DataException {
+ byte[] creationBytes = BTCACCT.buildQortalAT(tradeAddress, bitcoinPublicKeyHash, hashOfSecretB, redeemAmount, bitcoinAmount, tradeTimeout);
long txTimestamp = System.currentTimeMillis();
byte[] lastReference = deployer.getLastReference();
@@ -752,4 +784,9 @@ public class AtTests extends Common {
}
}
+ private PrivateKeyAccount createTradeAccount(Repository repository) {
+ // We actually use a known test account with funds to avoid PoW compute
+ return Common.getTestAccount(repository, "alice");
+ }
+
}