Coverage Summary for Class: RskAllowUnconfirmedCoinSelector (co.rsk.peg.bitcoin)

Class Method, % Line, %
RskAllowUnconfirmedCoinSelector 0% (0/3) 0% (0/14)
RskAllowUnconfirmedCoinSelector$1 0% (0/2) 0% (0/8)
Total 0% (0/5) 0% (0/22)


1 /* 2  * This file is part of RskJ 3  * Copyright (C) 2017 RSK Labs Ltd. 4  * 5  * This program is free software: you can redistribute it and/or modify 6  * it under the terms of the GNU Lesser General Public License as published by 7  * the Free Software Foundation, either version 3 of the License, or 8  * (at your option) any later version. 9  * 10  * This program is distributed in the hope that it will be useful, 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13  * GNU Lesser General Public License for more details. 14  * 15  * You should have received a copy of the GNU Lesser General Public License 16  * along with this program. If not, see <http://www.gnu.org/licenses/>. 17  */ 18  19 package co.rsk.peg.bitcoin; 20  21 import com.google.common.annotations.VisibleForTesting; 22 import co.rsk.bitcoinj.core.Coin; 23 import co.rsk.bitcoinj.core.NetworkParameters; 24 import co.rsk.bitcoinj.core.TransactionOutput; 25 import co.rsk.bitcoinj.wallet.CoinSelector; 26 import co.rsk.bitcoinj.wallet.CoinSelection; 27  28 import java.math.BigInteger; 29 import java.util.ArrayList; 30 import java.util.Collections; 31 import java.util.Comparator; 32 import java.util.List; 33  34 /** 35  * Custom Coin selector : 36  * All outputs are selectable (like AllowUnconfirmedCoinSelector). We don't know how many confirmations an output has, but we just add them to the wallet once they have a lot of confirmations 37  * Sorts outputs just by hash number (ignores output value and number of confirmation) which produces a pseudo random order. 38  * Created by mario on 05/10/2016. 39  */ 40 public class RskAllowUnconfirmedCoinSelector implements CoinSelector{ 41  42  @Override 43  public CoinSelection select(Coin target, List<TransactionOutput> candidates) { 44  ArrayList<TransactionOutput> selected = new ArrayList<TransactionOutput>(); 45  // Sort the inputs by age*value so we get the highest "coindays" spent. 46  // TODO: Consider changing the wallets internal format to track just outputs and keep them ordered. 47  ArrayList<TransactionOutput> sortedOutputs = new ArrayList<TransactionOutput>(candidates); 48  // When calculating the wallet balance, we may be asked to select all possible coins, if so, avoid sorting 49  // them in order to improve performance. 50  // TODO: Take in network parameters when instanatiated, and then test against the current network. Or just have a boolean parameter for "give me everything" 51  if (!target.equals(NetworkParameters.MAX_MONEY)) { 52  sortOutputs(sortedOutputs); 53  } 54  // Now iterate over the sorted outputs until we have got as close to the target as possible or a little 55  // bit over (excessive value will be change). 56  long total = 0; 57  for (TransactionOutput output : sortedOutputs) { 58  if (total >= target.value) { 59  break; 60  } 61  62  selected.add(output); 63  total += output.getValue().value; 64  } 65  // Total may be lower than target here, if the given candidates were insufficient to create to requested 66  // transaction. 67  return new CoinSelection(Coin.valueOf(total), selected); 68  } 69  70  @VisibleForTesting 71  public void sortOutputs(List<TransactionOutput> outputs) { 72  Collections.sort(outputs, new Comparator<TransactionOutput>() { 73  @Override 74  public int compare(TransactionOutput a, TransactionOutput b) { 75  a.getIndex(); 76  BigInteger aHash = a.getParentTransactionHash().toBigInteger(); 77  BigInteger bHash = b.getParentTransactionHash().toBigInteger(); 78  int ret = aHash.compareTo(bHash); 79  if(ret == 0) { 80  ret = Integer.compare(a.getIndex(), b.getIndex()); 81  } 82  return ret; 83  } 84  }); 85  } 86 }