package io.bitsquare.btc.blockchain; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.SettableFuture; import com.google.inject.Inject; import io.bitsquare.app.Log; import io.bitsquare.btc.blockchain.providers.BlockTrailProvider; import io.bitsquare.btc.blockchain.providers.BlockrIOProvider; import io.bitsquare.btc.blockchain.providers.FeeProvider; import io.bitsquare.btc.blockchain.providers.TradeBlockProvider; import org.bitcoinj.core.Coin; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Arrays; public class BlockchainService { private static final Logger log = LoggerFactory.getLogger(BlockchainService.class); private final ArrayList<FeeProvider> feeProviders; @Inject public BlockchainService(BlockrIOProvider blockrIOProvider, BlockTrailProvider blockTrailProvider, TradeBlockProvider tradeBlockProvider) { feeProviders = new ArrayList<>(Arrays.asList(blockrIOProvider, blockTrailProvider, tradeBlockProvider)); } public SettableFuture<Coin> requestFee(String transactionId) { Log.traceCall(transactionId); long startTime = System.currentTimeMillis(); final SettableFuture<Coin> resultFuture = SettableFuture.create(); for (FeeProvider provider : feeProviders) { GetFeeRequest getFeeRequest = new GetFeeRequest(); SettableFuture<Coin> future = getFeeRequest.request(transactionId, provider); Futures.addCallback(future, new FutureCallback<Coin>() { public void onSuccess(Coin fee) { if (!resultFuture.isDone()) { log.debug("Request fee from providers done after {} ms.", (System.currentTimeMillis() - startTime)); resultFuture.set(fee); } } public void onFailure(@NotNull Throwable throwable) { if (!resultFuture.isDone()) { log.warn("Could not get the fee from any provider after repeated requests."); resultFuture.setException(throwable); } } }); } return resultFuture; } }