Search in sources :

Example 11 with Coin

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));
}
Also used : Context(co.rsk.bitcoinj.core.Context) Coin(co.rsk.bitcoinj.core.Coin) Script(co.rsk.bitcoinj.script.Script) BtcTransaction(co.rsk.bitcoinj.core.BtcTransaction) ActivationConfigsForTest(org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest) Test(org.junit.Test)

Example 12 with Coin

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);
}
Also used : Coin(co.rsk.bitcoinj.core.Coin) Wallet(co.rsk.bitcoinj.wallet.Wallet)

Example 13 with Coin

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);
}
Also used : Coin(co.rsk.bitcoinj.core.Coin)

Example 14 with Coin

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);
    }
}
Also used : OneOffWhiteListEntry(co.rsk.peg.whitelist.OneOffWhiteListEntry) Arrays(java.util.Arrays) VMException(org.ethereum.vm.exception.VMException) BtcLockSenderProvider(co.rsk.peg.btcLockSender.BtcLockSenderProvider) Address(co.rsk.bitcoinj.core.Address) LoggerFactory(org.slf4j.LoggerFactory) RskAddress(co.rsk.core.RskAddress) UTXOProviderException(co.rsk.bitcoinj.core.UTXOProviderException) TxSenderAddressType(co.rsk.peg.btcLockSender.BtcLockSender.TxSenderAddressType) Keccak256(co.rsk.crypto.Keccak256) RSKIP219(org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP219) Sha256Hash(co.rsk.bitcoinj.core.Sha256Hash) ActivationConfig(org.ethereum.config.blockchain.upgrades.ActivationConfig) TransactionSignature(co.rsk.bitcoinj.crypto.TransactionSignature) Context(co.rsk.bitcoinj.core.Context) Pair(org.apache.commons.lang3.tuple.Pair) BtcBlockChain(co.rsk.bitcoinj.core.BtcBlockChain) Map(java.util.Map) BigInteger(java.math.BigInteger) PrecompiledContracts(org.ethereum.vm.PrecompiledContracts) RSKIP186(org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP186) MerkleBranch(co.rsk.peg.bitcoin.MerkleBranch) Wallet(co.rsk.bitcoinj.wallet.Wallet) Coin(co.rsk.bitcoinj.core.Coin) TransactionOutput(co.rsk.bitcoinj.core.TransactionOutput) FastBridgeRedeemScriptParser(co.rsk.bitcoinj.script.FastBridgeRedeemScriptParser) Set(java.util.Set) CallType(co.rsk.rpc.modules.trace.CallType) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) Repository(org.ethereum.core.Repository) TransactionInput(co.rsk.bitcoinj.core.TransactionInput) Objects(java.util.Objects) ScriptBuilder(co.rsk.bitcoinj.script.ScriptBuilder) Script(co.rsk.bitcoinj.script.Script) List(java.util.List) VerificationException(co.rsk.bitcoinj.core.VerificationException) Optional(java.util.Optional) UTXO(co.rsk.bitcoinj.core.UTXO) BtcBlock(co.rsk.bitcoinj.core.BtcBlock) LockWhitelistEntry(co.rsk.peg.whitelist.LockWhitelistEntry) CheckpointManager(co.rsk.bitcoinj.core.CheckpointManager) NetworkParameters(co.rsk.bitcoinj.core.NetworkParameters) co.rsk.peg.utils(co.rsk.peg.utils) ProgramSubtrace(co.rsk.rpc.modules.trace.ProgramSubtrace) PeginInstructionsProvider(co.rsk.peg.pegininstructions.PeginInstructionsProvider) ArrayList(java.util.ArrayList) Hex(org.bouncycastle.util.encoders.Hex) Block(org.ethereum.core.Block) BridgeUtils.getRegularPegoutTxSize(co.rsk.peg.BridgeUtils.getRegularPegoutTxSize) InsufficientMoneyException(co.rsk.bitcoinj.core.InsufficientMoneyException) BridgeConstants(co.rsk.config.BridgeConstants) Nullable(javax.annotation.Nullable) AddressFormatException(co.rsk.bitcoinj.core.AddressFormatException) BtcECKey(co.rsk.bitcoinj.core.BtcECKey) PanicProcessor(co.rsk.panic.PanicProcessor) FastBridgeFederationInformation(co.rsk.peg.fastbridge.FastBridgeFederationInformation) ScriptChunk(co.rsk.bitcoinj.script.ScriptChunk) Logger(org.slf4j.Logger) CoinbaseInformation(co.rsk.peg.bitcoin.CoinbaseInformation) HashUtil(org.ethereum.crypto.HashUtil) DataWord(org.ethereum.vm.DataWord) IOException(java.io.IOException) LockWhitelist(co.rsk.peg.whitelist.LockWhitelist) SendRequest(co.rsk.bitcoinj.wallet.SendRequest) BtcTransaction(co.rsk.bitcoinj.core.BtcTransaction) Program(org.ethereum.vm.program.Program) UnlimitedWhiteListEntry(co.rsk.peg.whitelist.UnlimitedWhiteListEntry) BlockStoreException(co.rsk.bitcoinj.store.BlockStoreException) PartialMerkleTree(co.rsk.bitcoinj.core.PartialMerkleTree) ByteUtil(org.ethereum.util.ByteUtil) InternalTransaction(org.ethereum.vm.program.InternalTransaction) PeginInstructionsException(co.rsk.peg.pegininstructions.PeginInstructionsException) RskAllowUnconfirmedCoinSelector(co.rsk.peg.bitcoin.RskAllowUnconfirmedCoinSelector) VisibleForTesting(com.google.common.annotations.VisibleForTesting) ProgramResult(org.ethereum.vm.program.ProgramResult) StoredBlock(co.rsk.bitcoinj.core.StoredBlock) Transaction(org.ethereum.core.Transaction) Collections(java.util.Collections) ConsensusRule(org.ethereum.config.blockchain.upgrades.ConsensusRule) TransferInvoke(org.ethereum.vm.program.invoke.TransferInvoke) InputStream(java.io.InputStream) ECKey(org.ethereum.crypto.ECKey) UTXO(co.rsk.bitcoinj.core.UTXO) Coin(co.rsk.bitcoinj.core.Coin) Wallet(co.rsk.bitcoinj.wallet.Wallet) BtcTransaction(co.rsk.bitcoinj.core.BtcTransaction) List(java.util.List) ArrayList(java.util.ArrayList) VMException(org.ethereum.vm.exception.VMException) UTXOProviderException(co.rsk.bitcoinj.core.UTXOProviderException) VerificationException(co.rsk.bitcoinj.core.VerificationException) InsufficientMoneyException(co.rsk.bitcoinj.core.InsufficientMoneyException) AddressFormatException(co.rsk.bitcoinj.core.AddressFormatException) IOException(java.io.IOException) BlockStoreException(co.rsk.bitcoinj.store.BlockStoreException) PeginInstructionsException(co.rsk.peg.pegininstructions.PeginInstructionsException)

Example 15 with Coin

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);
    }
}
Also used : Coin(co.rsk.bitcoinj.core.Coin)

Aggregations

Coin (co.rsk.bitcoinj.core.Coin)19 BtcTransaction (co.rsk.bitcoinj.core.BtcTransaction)7 Address (co.rsk.bitcoinj.core.Address)6 Context (co.rsk.bitcoinj.core.Context)6 Script (co.rsk.bitcoinj.script.Script)6 RskAddress (co.rsk.core.RskAddress)6 Test (org.junit.Test)6 AddressFormatException (co.rsk.bitcoinj.core.AddressFormatException)4 NetworkParameters (co.rsk.bitcoinj.core.NetworkParameters)4 TransactionInput (co.rsk.bitcoinj.core.TransactionInput)4 Wallet (co.rsk.bitcoinj.wallet.Wallet)4 IOException (java.io.IOException)4 BigInteger (java.math.BigInteger)4 ActivationConfigsForTest (org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest)4 ECKey (org.ethereum.crypto.ECKey)4 VMException (org.ethereum.vm.exception.VMException)4 BtcECKey (co.rsk.bitcoinj.core.BtcECKey)3 InsufficientMoneyException (co.rsk.bitcoinj.core.InsufficientMoneyException)3 Sha256Hash (co.rsk.bitcoinj.core.Sha256Hash)3 UTXOProviderException (co.rsk.bitcoinj.core.UTXOProviderException)3