use of co.rsk.bitcoinj.core.Coin in project rskj by rsksmart.
the class BridgeUtilsTest method testIsValidPegInTx_less_than_minimum_not_pegin_after_iris.
@Test
public void testIsValidPegInTx_less_than_minimum_not_pegin_after_iris() {
// Tx sending less than the minimum allowed, not a peg-in tx
Context btcContext = new Context(networkParameters);
Federation federation = this.getGenesisFederationForTest(bridgeConstantsRegtest, btcContext);
when(activations.isActive(ConsensusRule.RSKIP219)).thenReturn(true);
Coin minimumPegInValueAfterIris = bridgeConstantsRegtest.getMinimumPeginTxValueInSatoshis();
// Tx sending less than the minimum allowed, not a peg-in tx
BtcTransaction tx = new BtcTransaction(networkParameters);
tx.addOutput(minimumPegInValueAfterIris.subtract(Coin.CENT), federation.getAddress());
tx.addInput(Sha256Hash.ZERO_HASH, 0, new Script(new byte[] {}));
assertFalse(BridgeUtils.isValidPegInTx(tx, federation, btcContext, bridgeConstantsRegtest, activations));
}
use of co.rsk.bitcoinj.core.Coin 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.core.Coin in project rskj by rsksmart.
the class BridgeSupport method getBtcLockedInFederation.
private Coin getBtcLockedInFederation() {
Coin maxRbtc = this.bridgeConstants.getMaxRbtc();
Coin currentBridgeBalance = rskRepository.getBalance(PrecompiledContracts.BRIDGE_ADDR).toBitcoin();
return maxRbtc.subtract(currentBridgeBalance);
}
use of co.rsk.bitcoinj.core.Coin 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.core.Coin in project rskj by rsksmart.
the class BridgeSupport method requestRelease.
/**
* Creates a request for BTC release and
* adds it to the request queue for it
* to be processed later.
*
* @param destinationAddress the destination BTC address.
* @param value the amount of BTC to release.
* @throws IOException
*/
private void requestRelease(Address destinationAddress, Coin value, Transaction rskTx) throws IOException {
Optional<RejectedPegoutReason> optionalRejectedPegoutReason = Optional.empty();
if (activations.isActive(RSKIP219)) {
int pegoutSize = getRegularPegoutTxSize(getActiveFederation());
Coin feePerKB = getFeePerKb();
// The pegout transaction has a cost related to its size and the current feePerKB
// The actual cost cannot be asserted exactly so the calculation is approximated
// On top of this, the remainder after the fee should be enough for the user to be able to operate
// For this, the calculation includes an additional percentage to assert for this
Coin requireFundsForFee = feePerKB.multiply(// times the size in bytes
pegoutSize).divide(// Get the s/b
1000);
requireFundsForFee = requireFundsForFee.add(requireFundsForFee.times(bridgeConstants.getMinimumPegoutValuePercentageToReceiveAfterFee()).divide(100));
// add the gap
// The pegout value should be greater or equals than the max of these two values
Coin minValue = Coin.valueOf(Math.max(bridgeConstants.getMinimumPegoutTxValueInSatoshis().value, requireFundsForFee.value));
// Since Iris the peg-out the rule is that the minimum is inclusive
if (value.isLessThan(minValue)) {
optionalRejectedPegoutReason = Optional.of(Objects.equals(minValue, requireFundsForFee) ? RejectedPegoutReason.FEE_ABOVE_VALUE : RejectedPegoutReason.LOW_AMOUNT);
}
} else {
// For legacy peg-outs the rule stated that the minimum was exclusive
if (!value.isGreaterThan(bridgeConstants.getLegacyMinimumPegoutTxValueInSatoshis())) {
optionalRejectedPegoutReason = Optional.of(RejectedPegoutReason.LOW_AMOUNT);
}
}
if (optionalRejectedPegoutReason.isPresent()) {
logger.warn("releaseBtc ignored. To {}. Tx {}. Value {}. Reason: {}", destinationAddress, rskTx, value, optionalRejectedPegoutReason.get());
if (activations.isActive(ConsensusRule.RSKIP185)) {
refundAndEmitRejectEvent(value, rskTx.getSender(), optionalRejectedPegoutReason.get());
}
} else {
if (activations.isActive(ConsensusRule.RSKIP146)) {
provider.getReleaseRequestQueue().add(destinationAddress, value, rskTx.getHash());
} else {
provider.getReleaseRequestQueue().add(destinationAddress, value);
}
if (activations.isActive(ConsensusRule.RSKIP185)) {
eventLogger.logReleaseBtcRequestReceived(rskTx.getSender().toHexString(), destinationAddress.getHash160(), value);
}
logger.info("releaseBtc succesful to {}. Tx {}. Value {}.", destinationAddress, rskTx, value);
}
}
Aggregations