Search in sources :

Example 1 with Coin

use of co.rsk.bitcoinj.core.Coin in project rskj by rsksmart.

the class BridgeSupport method verifyLockDoesNotSurpassLockingCap.

private boolean verifyLockDoesNotSurpassLockingCap(BtcTransaction btcTx, Coin totalAmount) {
    if (!activations.isActive(ConsensusRule.RSKIP134)) {
        return true;
    }
    Coin fedCurrentFunds = getBtcLockedInFederation();
    Coin lockingCap = this.getLockingCap();
    logger.trace("Evaluating locking cap for: TxId {}. Value to lock {}. Current funds {}. Current locking cap {}", btcTx.getHash(true), totalAmount, fedCurrentFunds, lockingCap);
    Coin fedUTXOsAfterThisLock = fedCurrentFunds.add(totalAmount);
    // If the federation funds (including this new UTXO) are smaller than or equals to the current locking cap, we are fine.
    if (fedUTXOsAfterThisLock.compareTo(lockingCap) <= 0) {
        return true;
    }
    logger.info("locking cap exceeded! btc Tx {}", btcTx);
    return false;
}
Also used : Coin(co.rsk.bitcoinj.core.Coin)

Example 2 with Coin

use of co.rsk.bitcoinj.core.Coin in project rskj by rsksmart.

the class BridgeSupport method processPegIn.

protected void processPegIn(BtcTransaction btcTx, Transaction rskTx, int height, Sha256Hash btcTxHash) throws IOException, RegisterBtcTransactionException {
    logger.debug("[processPegIn] This is a lock tx {}", btcTx);
    Coin totalAmount = computeTotalAmountSent(btcTx);
    PeginInformation peginInformation = new PeginInformation(btcLockSenderProvider, peginInstructionsProvider, activations);
    try {
        peginInformation.parse(btcTx);
    } catch (PeginInstructionsException e) {
        if (activations.isActive(ConsensusRule.RSKIP170)) {
            if (activations.isActive(ConsensusRule.RSKIP181)) {
                eventLogger.logRejectedPegin(btcTx, RejectedPeginReason.PEGIN_V1_INVALID_PAYLOAD);
            }
            // If possible to get the sender address, refund
            refundTxSender(btcTx, rskTx, peginInformation, totalAmount);
            markTxAsProcessed(btcTx);
        }
        String message = String.format("Error while trying to parse peg-in information for tx %s. %s", btcTx.getHash(), e.getMessage());
        logger.warn("[processPegIn] {}", message);
        throw new RegisterBtcTransactionException(message);
    }
    int protocolVersion = peginInformation.getProtocolVersion();
    logger.debug("[processPegIn] Protocol version: {}", protocolVersion);
    switch(protocolVersion) {
        case 0:
            processPegInVersionLegacy(btcTx, rskTx, height, peginInformation, totalAmount);
            break;
        case 1:
            processPegInVersion1(btcTx, rskTx, peginInformation, totalAmount);
            break;
        default:
            markTxAsProcessed(btcTx);
            String message = String.format("Invalid peg-in protocol version: %d", protocolVersion);
            logger.warn("[processPegIn] {}", message);
            throw new RegisterBtcTransactionException(message);
    }
    markTxAsProcessed(btcTx);
    logger.info("[processPegIn] BTC Tx {} processed in RSK", btcTxHash);
}
Also used : Coin(co.rsk.bitcoinj.core.Coin) PeginInstructionsException(co.rsk.peg.pegininstructions.PeginInstructionsException)

Example 3 with Coin

use of co.rsk.bitcoinj.core.Coin in project rskj by rsksmart.

the class BridgeSupport method addOneOffLockWhitelistAddress.

/**
 * Adds the given address to the lock whitelist.
 * Returns 1 upon success, or -1 if the address was
 * already in the whitelist.
 * @param addressBase58 the base58-encoded address to add to the whitelist
 * @param maxTransferValue the max amount of satoshis enabled to transfer for this address
 * @return 1 upon success, -1 if the address was already
 * in the whitelist, -2 if address is invalid
 * LOCK_WHITELIST_GENERIC_ERROR_CODE otherwise.
 */
public Integer addOneOffLockWhitelistAddress(Transaction tx, String addressBase58, BigInteger maxTransferValue) {
    try {
        Address address = getParsedAddress(addressBase58);
        Coin maxTransferValueCoin = Coin.valueOf(maxTransferValue.longValueExact());
        return this.addLockWhitelistAddress(tx, new OneOffWhiteListEntry(address, maxTransferValueCoin));
    } catch (AddressFormatException e) {
        logger.warn(INVALID_ADDRESS_FORMAT_MESSAGE, e);
        return LOCK_WHITELIST_INVALID_ADDRESS_FORMAT_ERROR_CODE;
    }
}
Also used : Coin(co.rsk.bitcoinj.core.Coin) AddressFormatException(co.rsk.bitcoinj.core.AddressFormatException) Address(co.rsk.bitcoinj.core.Address) RskAddress(co.rsk.core.RskAddress) OneOffWhiteListEntry(co.rsk.peg.whitelist.OneOffWhiteListEntry)

Example 4 with Coin

use of co.rsk.bitcoinj.core.Coin in project rskj by rsksmart.

the class BridgeSupport method increaseLockingCap.

public boolean increaseLockingCap(Transaction tx, Coin newCap) {
    // Only pre configured addresses can modify locking cap
    AddressBasedAuthorizer authorizer = bridgeConstants.getIncreaseLockingCapAuthorizer();
    if (!authorizer.isAuthorized(tx)) {
        logger.warn("not authorized address tried to increase locking cap. Address: {}", tx.getSender());
        return false;
    }
    // new locking cap must be bigger than current locking cap
    Coin currentLockingCap = this.getLockingCap();
    if (newCap.compareTo(currentLockingCap) < 0) {
        logger.warn("attempted value doesn't increase locking cap. Attempted: {}", newCap.value);
        return false;
    }
    Coin maxLockingCap = currentLockingCap.multiply(bridgeConstants.getLockingCapIncrementsMultiplier());
    if (newCap.compareTo(maxLockingCap) > 0) {
        logger.warn("attempted value increases locking cap above its limit. Attempted: {}", newCap.value);
        return false;
    }
    logger.info("increased locking cap: {}", newCap.value);
    this.provider.setLockingCap(newCap);
    return true;
}
Also used : Coin(co.rsk.bitcoinj.core.Coin)

Example 5 with Coin

use of co.rsk.bitcoinj.core.Coin in project rskj by rsksmart.

the class BridgeSupport method registerFastBridgeBtcTransaction.

public BigInteger registerFastBridgeBtcTransaction(Transaction rskTx, byte[] btcTxSerialized, int height, byte[] pmtSerialized, Keccak256 derivationArgumentsHash, Address userRefundAddress, RskAddress lbcAddress, Address lpBtcAddress, boolean shouldTransferToContract) throws BlockStoreException, IOException, BridgeIllegalArgumentException {
    if (!BridgeUtils.isContractTx(rskTx)) {
        logger.debug("[registerFastBridgeBtcTransaction] (rskTx:{}) Sender not a contract", rskTx.getHash());
        return BigInteger.valueOf(FAST_BRIDGE_UNPROCESSABLE_TX_NOT_CONTRACT_ERROR_CODE);
    }
    if (!rskTx.getSender().equals(lbcAddress)) {
        logger.debug("[registerFastBridgeBtcTransaction] Expected sender to be the same as lbcAddress. (sender: {}) (lbcAddress:{})", rskTx.getSender(), lbcAddress);
        return BigInteger.valueOf(FAST_BRIDGE_UNPROCESSABLE_TX_INVALID_SENDER_ERROR_CODE);
    }
    Context.propagate(btcContext);
    Sha256Hash btcTxHash = BtcTransactionFormatUtils.calculateBtcTxHash(btcTxSerialized);
    Keccak256 fastBridgeDerivationHash = getFastBridgeDerivationHash(derivationArgumentsHash, userRefundAddress, lpBtcAddress, lbcAddress);
    if (provider.isFastBridgeFederationDerivationHashUsed(btcTxHash, fastBridgeDerivationHash)) {
        logger.debug("[registerFastBridgeBtcTransaction] Transaction and derivation hash already used");
        return BigInteger.valueOf(FAST_BRIDGE_UNPROCESSABLE_TX_ALREADY_PROCESSED_ERROR_CODE);
    }
    if (!validationsForRegisterBtcTransaction(btcTxHash, height, pmtSerialized, btcTxSerialized)) {
        logger.debug("[registerFastBridgeBtcTransaction] (btcTx:{}) error during validationsForRegisterBtcTransaction", btcTxHash);
        return BigInteger.valueOf(FAST_BRIDGE_UNPROCESSABLE_TX_VALIDATIONS_ERROR);
    }
    BtcTransaction btcTx = new BtcTransaction(bridgeConstants.getBtcParams(), btcTxSerialized);
    btcTx.verify();
    Sha256Hash btcTxHashWithoutWitness = btcTx.getHash(false);
    if (!btcTxHashWithoutWitness.equals(btcTxHash) && provider.isFastBridgeFederationDerivationHashUsed(btcTxHashWithoutWitness, derivationArgumentsHash)) {
        logger.debug("[registerFastBridgeBtcTransaction] Transaction and derivation hash already used");
        return BigInteger.valueOf(FAST_BRIDGE_UNPROCESSABLE_TX_ALREADY_PROCESSED_ERROR_CODE);
    }
    FastBridgeFederationInformation fastBridgeFederationInformation = createFastBridgeFederationInformation(fastBridgeDerivationHash);
    Address fastBridgeFedAddress = fastBridgeFederationInformation.getFastBridgeFederationAddress(bridgeConstants.getBtcParams());
    Coin totalAmount = getAmountSentToAddress(btcTx, fastBridgeFedAddress);
    if (totalAmount == Coin.ZERO) {
        logger.debug("[registerFastBridgeBtcTransaction] Amount sent can't be 0");
        return BigInteger.valueOf(FAST_BRIDGE_UNPROCESSABLE_TX_VALUE_ZERO_ERROR);
    }
    if (!verifyLockDoesNotSurpassLockingCap(btcTx, totalAmount)) {
        InternalTransaction internalTx = (InternalTransaction) rskTx;
        logger.info("[registerFastBridgeBtcTransaction] Locking cap surpassed, going to return funds!");
        WalletProvider walletProvider = createFastBridgeWalletProvider(fastBridgeFederationInformation);
        provider.markFastBridgeFederationDerivationHashAsUsed(btcTxHash, fastBridgeDerivationHash);
        if (shouldTransferToContract) {
            logger.debug("[registerFastBridgeBtcTransaction] Returning to liquidity provider");
            generateRejectionRelease(btcTx, lpBtcAddress, fastBridgeFedAddress, new Keccak256(internalTx.getOriginHash()), totalAmount, walletProvider);
            return BigInteger.valueOf(FAST_BRIDGE_REFUNDED_LP_ERROR_CODE);
        } else {
            logger.debug("[registerFastBridgeBtcTransaction] Returning to user");
            generateRejectionRelease(btcTx, userRefundAddress, fastBridgeFedAddress, new Keccak256(internalTx.getOriginHash()), totalAmount, walletProvider);
            return BigInteger.valueOf(FAST_BRIDGE_REFUNDED_USER_ERROR_CODE);
        }
    }
    transferTo(lbcAddress, co.rsk.core.Coin.fromBitcoin(totalAmount));
    saveFastBridgeDataInStorage(btcTxHashWithoutWitness, fastBridgeDerivationHash, fastBridgeFederationInformation, getUTXOsForAddress(btcTx, fastBridgeFedAddress));
    logger.info("[registerFastBridgeBtcTransaction] (btcTx:{}) transaction registered successfully", btcTxHashWithoutWitness);
    return co.rsk.core.Coin.fromBitcoin(totalAmount).asBigInteger();
}
Also used : Coin(co.rsk.bitcoinj.core.Coin) Address(co.rsk.bitcoinj.core.Address) RskAddress(co.rsk.core.RskAddress) Sha256Hash(co.rsk.bitcoinj.core.Sha256Hash) BtcTransaction(co.rsk.bitcoinj.core.BtcTransaction) Keccak256(co.rsk.crypto.Keccak256) InternalTransaction(org.ethereum.vm.program.InternalTransaction) FastBridgeFederationInformation(co.rsk.peg.fastbridge.FastBridgeFederationInformation)

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