@@ -948,7 +948,7 @@ private void doProcessPendingOffer(List<OpenOffer> openOffers, OpenOffer openOff
948
948
if (openOffer .getScheduledTxHashes () != null ) {
949
949
boolean scheduledTxsAvailable = true ;
950
950
for (MoneroTxWallet tx : xmrWalletService .getTxs (openOffer .getScheduledTxHashes ())) {
951
- if (!tx .isLocked () && !isOutputsAvailable (tx )) {
951
+ if (!tx .isLocked () && !hasSpendableAmount (tx )) {
952
952
scheduledTxsAvailable = false ;
953
953
break ;
954
954
}
@@ -1165,31 +1165,21 @@ private void scheduleWithEarliestTxs(List<OpenOffer> openOffers, OpenOffer openO
1165
1165
throw new RuntimeException ("Not enough money in Haveno wallet" );
1166
1166
}
1167
1167
1168
- // get earliest available or pending txs with sufficient incoming amount
1168
+ // get earliest available or pending txs with sufficient spendable amount
1169
1169
BigInteger scheduledAmount = BigInteger .ZERO ;
1170
1170
Set <MoneroTxWallet > scheduledTxs = new HashSet <MoneroTxWallet >();
1171
1171
for (MoneroTxWallet tx : xmrWalletService .getTxs ()) {
1172
1172
1173
- // skip if no funds available
1174
- BigInteger sentToSelfAmount = xmrWalletService .getAmountSentToSelf (tx ); // amount sent to self always shows 0, so compute from destinations manually
1175
- if (sentToSelfAmount .equals (BigInteger .ZERO ) && (tx .getIncomingTransfers () == null || tx .getIncomingTransfers ().isEmpty ())) continue ;
1176
- if (!isOutputsAvailable (tx )) continue ;
1173
+ // get spendable amount
1174
+ BigInteger spendableAmount = getSpendableAmount (tx );
1175
+
1176
+ // skip if no spendable amount or already scheduled
1177
+ if (spendableAmount .equals (BigInteger .ZERO )) continue ;
1177
1178
if (isTxScheduledByOtherOffer (openOffers , openOffer , tx .getHash ())) continue ;
1178
1179
1179
- // schedule transaction if funds sent to self, because they are not included in incoming transfers // TODO: fix in libraries?
1180
- if (sentToSelfAmount .compareTo (BigInteger .ZERO ) > 0 ) {
1181
- scheduledAmount = scheduledAmount .add (sentToSelfAmount );
1182
- scheduledTxs .add (tx );
1183
- } else if (tx .getIncomingTransfers () != null ) {
1184
-
1185
- // schedule transaction if incoming tranfers to account 0
1186
- for (MoneroIncomingTransfer transfer : tx .getIncomingTransfers ()) {
1187
- if (transfer .getAccountIndex () == 0 ) {
1188
- scheduledAmount = scheduledAmount .add (transfer .getAmount ());
1189
- scheduledTxs .add (tx );
1190
- }
1191
- }
1192
- }
1180
+ // schedule tx
1181
+ scheduledAmount = scheduledAmount .add (spendableAmount );
1182
+ scheduledTxs .add (tx );
1193
1183
1194
1184
// break if sufficient funds
1195
1185
if (scheduledAmount .compareTo (offerReserveAmount ) >= 0 ) break ;
@@ -1202,6 +1192,34 @@ private void scheduleWithEarliestTxs(List<OpenOffer> openOffers, OpenOffer openO
1202
1192
openOffer .setState (OpenOffer .State .PENDING );
1203
1193
}
1204
1194
1195
+ private BigInteger getSpendableAmount (MoneroTxWallet tx ) {
1196
+
1197
+ // compute spendable amount from outputs if confirmed
1198
+ if (tx .isConfirmed ()) {
1199
+ BigInteger spendableAmount = BigInteger .ZERO ;
1200
+ if (tx .getOutputsWallet () != null ) {
1201
+ for (MoneroOutputWallet output : tx .getOutputsWallet ()) {
1202
+ if (!output .isSpent () && !output .isFrozen () && output .getAccountIndex () == 0 ) {
1203
+ spendableAmount = spendableAmount .add (output .getAmount ());
1204
+ }
1205
+ }
1206
+ }
1207
+ return spendableAmount ;
1208
+ }
1209
+
1210
+ // funds sent to self always show 0 incoming amount, so compute from destinations manually
1211
+ // TODO: this excludes change output, so change is missing from spendable amount until confirmed
1212
+ BigInteger sentToSelfAmount = xmrWalletService .getAmountSentToSelf (tx );
1213
+ if (sentToSelfAmount .compareTo (BigInteger .ZERO ) > 0 ) return sentToSelfAmount ;
1214
+
1215
+ // if not confirmed and not sent to self, return incoming amount
1216
+ return tx .getIncomingAmount () == null ? BigInteger .ZERO : tx .getIncomingAmount ();
1217
+ }
1218
+
1219
+ private boolean hasSpendableAmount (MoneroTxWallet tx ) {
1220
+ return getSpendableAmount (tx ).compareTo (BigInteger .ZERO ) > 0 ;
1221
+ }
1222
+
1205
1223
private BigInteger getScheduledAmount (List <OpenOffer > openOffers ) {
1206
1224
BigInteger scheduledAmount = BigInteger .ZERO ;
1207
1225
for (OpenOffer openOffer : openOffers ) {
@@ -1233,14 +1251,6 @@ private boolean isTxScheduledByOtherOffer(List<OpenOffer> openOffers, OpenOffer
1233
1251
return false ;
1234
1252
}
1235
1253
1236
- private boolean isOutputsAvailable (MoneroTxWallet tx ) {
1237
- if (tx .getOutputsWallet () == null ) return false ;
1238
- for (MoneroOutputWallet output : tx .getOutputsWallet ()) {
1239
- if (output .isSpent () || output .isFrozen ()) return false ;
1240
- }
1241
- return true ;
1242
- }
1243
-
1244
1254
private void signAndPostOffer (OpenOffer openOffer ,
1245
1255
boolean useSavingsWallet , // TODO: remove this?
1246
1256
TransactionResultHandler resultHandler , ErrorMessageHandler errorMessageHandler ) {
0 commit comments