use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.
the class BridgeSupport method computeTotalAmountSent.
private Coin computeTotalAmountSent(BtcTransaction btcTx) throws IOException {
// Compute the total amount sent. Value could have been sent both to the
// currently active federation as well as to the currently retiring federation.
// Add both amounts up in that case.
Coin amountToActive = btcTx.getValueSentToMe(getActiveFederationWallet(false));
Coin amountToRetiring = Coin.ZERO;
Wallet retiringFederationWallet = getRetiringFederationWallet(false);
if (retiringFederationWallet != null) {
amountToRetiring = btcTx.getValueSentToMe(retiringFederationWallet);
}
return amountToActive.add(amountToRetiring);
}
use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.
the class BridgeSupport method processFundsMigration.
private void processFundsMigration(Transaction rskTx) throws IOException {
Wallet retiringFederationWallet = getRetiringFederationWallet(true);
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
if (activations.isActive(ConsensusRule.RSKIP146)) {
Coin amountMigrated = selectedUTXOs.stream().map(UTXO::getValue).reduce(Coin.ZERO, Coin::add);
releaseTransactionSet.add(btcTx, rskExecutionBlock.getNumber(), rskTx.getHash());
// Log the Release request
eventLogger.logReleaseBtcRequested(rskTx.getHash().getBytes(), btcTx, amountMigrated);
} else {
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
if (activations.isActive(ConsensusRule.RSKIP146)) {
Coin amountMigrated = selectedUTXOs.stream().map(UTXO::getValue).reduce(Coin.ZERO, Coin::add);
releaseTransactionSet.add(btcTx, rskExecutionBlock.getNumber(), rskTx.getHash());
// Log the Release request
eventLogger.logReleaseBtcRequested(rskTx.getHash().getBytes(), btcTx, amountMigrated);
} else {
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 getFastBridgeWallet.
protected Wallet getFastBridgeWallet(Context btcContext, List<UTXO> utxos, FastBridgeFederationInformation fb) {
Wallet wallet = new FastBridgeCompatibleBtcWalletWithSingleScript(btcContext, getLiveFederations(), fb);
RskUTXOProvider utxoProvider = new RskUTXOProvider(btcContext.getParams(), utxos);
wallet.setUTXOProvider(utxoProvider);
wallet.setCoinSelector(new RskAllowUnconfirmedCoinSelector());
return wallet;
}
use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.
the class BridgeSupport method createMigrationTransaction.
private Pair<BtcTransaction, List<UTXO>> createMigrationTransaction(Wallet originWallet, Address destinationAddress) {
Coin expectedMigrationValue = originWallet.getBalance();
logger.debug("[createMigrationTransaction] Balance to migrate: {}", expectedMigrationValue);
for (; ; ) {
BtcTransaction migrationBtcTx = new BtcTransaction(originWallet.getParams());
migrationBtcTx.addOutput(expectedMigrationValue, destinationAddress);
SendRequest sr = SendRequest.forTx(migrationBtcTx);
sr.changeAddress = destinationAddress;
sr.feePerKb = getFeePerKb();
sr.missingSigsMode = Wallet.MissingSigsMode.USE_OP_ZERO;
sr.recipientsPayFees = true;
try {
originWallet.completeTx(sr);
for (TransactionInput transactionInput : migrationBtcTx.getInputs()) {
transactionInput.disconnect();
}
List<UTXO> selectedUTXOs = originWallet.getUTXOProvider().getOpenTransactionOutputs(originWallet.getWatchedAddresses()).stream().filter(utxo -> migrationBtcTx.getInputs().stream().anyMatch(input -> input.getOutpoint().getHash().equals(utxo.getHash()) && input.getOutpoint().getIndex() == utxo.getIndex())).collect(Collectors.toList());
return Pair.of(migrationBtcTx, selectedUTXOs);
} catch (InsufficientMoneyException | Wallet.ExceededMaxTransactionSize | Wallet.CouldNotAdjustDownwards e) {
expectedMigrationValue = expectedMigrationValue.divide(2);
} catch (Wallet.DustySendRequested e) {
throw new IllegalStateException("Retiring federation wallet cannot be emptied", e);
} catch (UTXOProviderException e) {
throw new RuntimeException("Unexpected UTXO provider error", e);
}
}
}
Aggregations