diff --git a/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv1TradeBot.java b/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv1TradeBot.java index 60ca14b7..5af8aa45 100644 --- a/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv1TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv1TradeBot.java @@ -387,32 +387,32 @@ public class BitcoinACCTv1TradeBot implements AcctTradeBot { break; case ALICE_WAITING_FOR_P2SH_A: - TradeBot.getInstance().updatePresence(repository, tradeBotData); + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); handleAliceWaitingForP2shA(repository, tradeBotData, atData, tradeData); break; case BOB_WAITING_FOR_MESSAGE: - TradeBot.getInstance().updatePresence(repository, tradeBotData); + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); handleBobWaitingForMessage(repository, tradeBotData, atData, tradeData); break; case ALICE_WAITING_FOR_AT_LOCK: - TradeBot.getInstance().updatePresence(repository, tradeBotData); + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); handleAliceWaitingForAtLock(repository, tradeBotData, atData, tradeData); break; case BOB_WAITING_FOR_P2SH_B: - TradeBot.getInstance().updatePresence(repository, tradeBotData); + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); handleBobWaitingForP2shB(repository, tradeBotData, atData, tradeData); break; case ALICE_WATCH_P2SH_B: - TradeBot.getInstance().updatePresence(repository, tradeBotData); + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); handleAliceWatchingP2shB(repository, tradeBotData, atData, tradeData); break; case BOB_WAITING_FOR_AT_REDEEM: - TradeBot.getInstance().updatePresence(repository, tradeBotData); + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); handleBobWaitingForAtRedeem(repository, tradeBotData, atData, tradeData); break; @@ -421,12 +421,12 @@ public class BitcoinACCTv1TradeBot implements AcctTradeBot { break; case ALICE_REFUNDING_B: - TradeBot.getInstance().updatePresence(repository, tradeBotData); + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); handleAliceRefundingP2shB(repository, tradeBotData, atData, tradeData); break; case ALICE_REFUNDING_A: - TradeBot.getInstance().updatePresence(repository, tradeBotData); + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); handleAliceRefundingP2shA(repository, tradeBotData, atData, tradeData); break; diff --git a/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv1TradeBot.java b/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv1TradeBot.java index 5fc8b3ab..b87b2bcf 100644 --- a/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv1TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv1TradeBot.java @@ -384,17 +384,17 @@ public class LitecoinACCTv1TradeBot implements AcctTradeBot { break; case BOB_WAITING_FOR_MESSAGE: - TradeBot.getInstance().updatePresence(repository, tradeBotData); + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); handleBobWaitingForMessage(repository, tradeBotData, atData, tradeData); break; case ALICE_WAITING_FOR_AT_LOCK: - TradeBot.getInstance().updatePresence(repository, tradeBotData); + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); handleAliceWaitingForAtLock(repository, tradeBotData, atData, tradeData); break; case BOB_WAITING_FOR_AT_REDEEM: - TradeBot.getInstance().updatePresence(repository, tradeBotData); + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); handleBobWaitingForAtRedeem(repository, tradeBotData, atData, tradeData); break; @@ -403,7 +403,7 @@ public class LitecoinACCTv1TradeBot implements AcctTradeBot { break; case ALICE_REFUNDING_A: - TradeBot.getInstance().updatePresence(repository, tradeBotData); + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); handleAliceRefundingP2shA(repository, tradeBotData, atData, tradeData); break; diff --git a/src/main/java/org/qortal/controller/tradebot/TradeBot.java b/src/main/java/org/qortal/controller/tradebot/TradeBot.java index b37d3b76..d98e8fa7 100644 --- a/src/main/java/org/qortal/controller/tradebot/TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/TradeBot.java @@ -307,20 +307,32 @@ public class TradeBot implements Listener { } // PRESENCE-related - /*package*/ void updatePresence(Repository repository, TradeBotData tradeBotData) throws DataException { - String key = tradeBotData.getAtAddress(); + /*package*/ void updatePresence(Repository repository, TradeBotData tradeBotData, CrossChainTradeData tradeData) + throws DataException { + String atAddress = tradeBotData.getAtAddress(); + + PrivateKeyAccount tradeNativeAccount = new PrivateKeyAccount(repository, tradeBotData.getTradePrivateKey()); + String signerAddress = tradeNativeAccount.getAddress(); + + /* + * There's no point in Alice trying to build a PRESENCE transaction + * for an AT that isn't locked to her, as other peers won't be able + * to validate the PRESENCE transaction as signing public key won't + * be visible. + */ + if (!signerAddress.equals(tradeData.qortalCreatorTradeAddress) && !signerAddress.equals(tradeData.qortalPartnerAddress)) + // Signer is neither Bob, nor Alice, or trade not yet locked to Alice + return; long now = NTP.getTime(); long threshold = now - PresenceType.TRADE_BOT.getLifetime(); - long timestamp = presenceTimestampsByAtAddress.compute(key, (k, v) -> (v == null || v < threshold) ? now : v); + long timestamp = presenceTimestampsByAtAddress.compute(atAddress, (k, v) -> (v == null || v < threshold) ? now : v); // If timestamp hasn't been updated then nothing to do if (timestamp != now) return; - PrivateKeyAccount tradeNativeAccount = new PrivateKeyAccount(repository, tradeBotData.getTradePrivateKey()); - int txGroupId = Group.NO_GROUP; byte[] reference = new byte[TransactionTransformer.SIGNATURE_LENGTH]; byte[] creatorPublicKey = tradeNativeAccount.getPublicKey(); diff --git a/src/main/java/org/qortal/transaction/PresenceTransaction.java b/src/main/java/org/qortal/transaction/PresenceTransaction.java index e5b96661..772928e9 100644 --- a/src/main/java/org/qortal/transaction/PresenceTransaction.java +++ b/src/main/java/org/qortal/transaction/PresenceTransaction.java @@ -168,15 +168,15 @@ public class PresenceTransaction extends Transaction { if (!Crypto.verify(this.transactionData.getCreatorPublicKey(), timestampSignature, timestampBytes)) return ValidationResult.INVALID_TIMESTAMP_SIGNATURE; - // Check signer is known trade address - String signerAddress = Crypto.toAddress(this.transactionData.getCreatorPublicKey()); - Map> acctSuppliersByCodeHash = SupportedBlockchain.getAcctMap(); Set codeHashes = acctSuppliersByCodeHash.keySet(); boolean isExecutable = true; List atsData = repository.getATRepository().getAllATsByFunctionality(codeHashes, isExecutable); + // Convert signer's public key to address form + String signerAddress = Crypto.toAddress(this.transactionData.getCreatorPublicKey()); + for (ATData atData : atsData) { ByteArray atCodeHash = new ByteArray(atData.getCodeHash()); Supplier acctSupplier = acctSuppliersByCodeHash.get(atCodeHash); @@ -185,7 +185,12 @@ public class PresenceTransaction extends Transaction { CrossChainTradeData crossChainTradeData = acctSupplier.get().populateTradeData(repository, atData); - if (crossChainTradeData.qortalCreatorTradeAddress.equals(signerAddress)) + // OK if signer's public key (in address form) matches Bob's trade public key (in address form) + if (signerAddress.equals(crossChainTradeData.qortalCreatorTradeAddress)) + return ValidationResult.OK; + + // OK if signer's public key (in address form) matches Alice's trade public key (in address form) + if (signerAddress.equals(crossChainTradeData.qortalPartnerAddress)) return ValidationResult.OK; }