use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.
the class BridgeSupport method processFundsMigration.
private void processFundsMigration() throws IOException {
Wallet retiringFederationWallet = getRetiringFederationWallet();
List<UTXO> availableUTXOs = getRetiringFederationBtcUTXOs();
ReleaseTransactionSet releaseTransactionSet = provider.getReleaseTransactionSet();
Federation activeFederation = getActiveFederation();
if (federationIsInMigrationAge(activeFederation) && hasMinimumFundsToMigrate(retiringFederationWallet)) {
logger.info("Active federation (age={}) is in migration age and retiring federation has funds to migrate: {}.", rskExecutionBlock.getNumber() - activeFederation.getCreationBlockNumber(), retiringFederationWallet.getBalance().toFriendlyString());
Pair<BtcTransaction, List<UTXO>> createResult = createMigrationTransaction(retiringFederationWallet, activeFederation.getAddress());
BtcTransaction btcTx = createResult.getLeft();
List<UTXO> selectedUTXOs = createResult.getRight();
// Add the TX to the release set
releaseTransactionSet.add(btcTx, rskExecutionBlock.getNumber());
// Mark UTXOs as spent
availableUTXOs.removeIf(utxo -> selectedUTXOs.stream().anyMatch(selectedUtxo -> utxo.getHash().equals(selectedUtxo.getHash()) && utxo.getIndex() == selectedUtxo.getIndex()));
}
if (retiringFederationWallet != null && federationIsPastMigrationAge(activeFederation)) {
if (retiringFederationWallet.getBalance().isGreaterThan(Coin.ZERO)) {
logger.info("Federation is past migration age and will try to migrate remaining balance: {}.", retiringFederationWallet.getBalance().toFriendlyString());
try {
Pair<BtcTransaction, List<UTXO>> createResult = createMigrationTransaction(retiringFederationWallet, activeFederation.getAddress());
BtcTransaction btcTx = createResult.getLeft();
List<UTXO> selectedUTXOs = createResult.getRight();
// Add the TX to the release set
releaseTransactionSet.add(btcTx, rskExecutionBlock.getNumber());
// Mark UTXOs as spent
availableUTXOs.removeIf(utxo -> selectedUTXOs.stream().anyMatch(selectedUtxo -> utxo.getHash().equals(selectedUtxo.getHash()) && utxo.getIndex() == selectedUtxo.getIndex()));
} catch (Exception e) {
logger.error("Unable to complete retiring federation migration. Balance left: {} in {}", retiringFederationWallet.getBalance().toFriendlyString(), getRetiringFederationAddress());
panicProcessor.panic("updateCollection", "Unable to complete retiring federation migration.");
}
}
logger.info("Retiring federation migration finished. Available UTXOs left: {}.", availableUTXOs.size());
provider.setOldFederation(null);
}
}
use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.
the class BridgeSupport method processReleaseRequests.
/**
* Processes the current btc release request queue
* and tries to build btc transactions using (and marking as spent)
* the current active federation's utxos.
* Newly created btc transactions are added to the btc release tx set,
* and failed attempts are kept in the release queue for future
* processing.
*/
private void processReleaseRequests() {
final Wallet activeFederationWallet;
final ReleaseRequestQueue releaseRequestQueue;
try {
activeFederationWallet = getActiveFederationWallet(true);
releaseRequestQueue = provider.getReleaseRequestQueue();
} catch (IOException e) {
logger.error("Unexpected error accessing storage while attempting to process release requests", e);
return;
}
// Releases are attempted using the currently active federation
// wallet.
final ReleaseTransactionBuilder txBuilder = new ReleaseTransactionBuilder(btcContext.getParams(), activeFederationWallet, getFederationAddress(), getFeePerKb(), activations);
releaseRequestQueue.process(MAX_RELEASE_ITERATIONS, (ReleaseRequestQueue.Entry releaseRequest) -> {
Optional<ReleaseTransactionBuilder.BuildResult> result = txBuilder.buildAmountTo(releaseRequest.getDestination(), releaseRequest.getAmount());
// Further logging is done at the tx builder level.
if (!result.isPresent()) {
logger.warn("Couldn't build a release BTC tx for <{}, {}>", releaseRequest.getDestination().toBase58(), releaseRequest.getAmount());
return false;
}
// We have a BTC transaction, mark the UTXOs as spent and add the tx
// to the release set.
List<UTXO> selectedUTXOs = result.get().getSelectedUTXOs();
BtcTransaction generatedTransaction = result.get().getBtcTx();
List<UTXO> availableUTXOs;
ReleaseTransactionSet releaseTransactionSet;
// the tx build and utxo selection, so treat as atomic)
try {
availableUTXOs = getActiveFederationBtcUTXOs();
releaseTransactionSet = provider.getReleaseTransactionSet();
} catch (IOException exception) {
// Unexpected error accessing storage, log and fail
logger.error(String.format("Unexpected error accessing storage while attempting to add a release BTC tx for <%s, %s>", releaseRequest.getDestination().toString(), releaseRequest.getAmount().toString()), exception);
return false;
}
if (activations.isActive(ConsensusRule.RSKIP146)) {
Keccak256 rskTxHash = releaseRequest.getRskTxHash();
// Add the TX
releaseTransactionSet.add(generatedTransaction, rskExecutionBlock.getNumber(), rskTxHash);
// We shouldn't generate the event for those releases
if (rskTxHash != null) {
// Log the Release request
eventLogger.logReleaseBtcRequested(rskTxHash.getBytes(), generatedTransaction, releaseRequest.getAmount());
}
} else {
releaseTransactionSet.add(generatedTransaction, rskExecutionBlock.getNumber());
}
// Mark UTXOs as spent
availableUTXOs.removeAll(selectedUTXOs);
// TODO: (Ariel Mendelzon, 07/12/2017)
// TODO: Balance adjustment assumes that change output is output with index 1.
// TODO: This will change if we implement multiple releases per BTC tx, so
// TODO: it would eventually need to be fixed.
// Adjust balances in edge cases
adjustBalancesIfChangeOutputWasDust(generatedTransaction, releaseRequest.getAmount());
return true;
});
}
use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.
the class BridgeSupport method saveNewUTXOs.
/*
Add the btcTx outputs that send btc to the federation(s) to the UTXO list
*/
private void saveNewUTXOs(BtcTransaction btcTx) throws IOException {
// Outputs to the active federation
List<TransactionOutput> outputsToTheActiveFederation = btcTx.getWalletOutputs(getActiveFederationWallet(false));
for (TransactionOutput output : outputsToTheActiveFederation) {
UTXO utxo = new UTXO(btcTx.getHash(), output.getIndex(), output.getValue(), 0, btcTx.isCoinBase(), output.getScriptPubKey());
getActiveFederationBtcUTXOs().add(utxo);
}
// Outputs to the retiring federation (if any)
Wallet retiringFederationWallet = getRetiringFederationWallet(false);
if (retiringFederationWallet != null) {
List<TransactionOutput> outputsToTheRetiringFederation = btcTx.getWalletOutputs(retiringFederationWallet);
for (TransactionOutput output : outputsToTheRetiringFederation) {
UTXO utxo = new UTXO(btcTx.getHash(), output.getIndex(), output.getValue(), 0, btcTx.isCoinBase(), output.getScriptPubKey());
getRetiringFederationBtcUTXOs().add(utxo);
}
}
}
use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.
the class BridgeUtils method getFederationsSpendWallet.
public static Wallet getFederationsSpendWallet(Context btcContext, List<Federation> federations, List<UTXO> utxos, boolean isFastBridgeCompatible, BridgeStorageProvider storageProvider) {
Wallet wallet;
if (isFastBridgeCompatible) {
wallet = new FastBridgeCompatibleBtcWalletWithStorage(btcContext, federations, storageProvider);
} else {
wallet = new BridgeBtcWallet(btcContext, federations);
}
RskUTXOProvider utxoProvider = new RskUTXOProvider(btcContext.getParams(), utxos);
wallet.setUTXOProvider(utxoProvider);
federations.forEach(federation -> wallet.addWatchedAddress(federation.getAddress(), federation.getCreationTime().toEpochMilli()));
wallet.setCoinSelector(new RskAllowUnconfirmedCoinSelector());
return wallet;
}
use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.
the class BridgeUtils method getFederationsNoSpendWallet.
public static Wallet getFederationsNoSpendWallet(Context btcContext, List<Federation> federations, boolean isFastBridgeCompatible, BridgeStorageProvider storageProvider) {
Wallet wallet;
if (isFastBridgeCompatible) {
wallet = new FastBridgeCompatibleBtcWalletWithStorage(btcContext, federations, storageProvider);
} else {
wallet = new BridgeBtcWallet(btcContext, federations);
}
federations.forEach(federation -> wallet.addWatchedAddress(federation.getAddress(), federation.getCreationTime().toEpochMilli()));
return wallet;
}
Aggregations