Search in sources :

Example 1 with FastBridgeFederationInformation

use of co.rsk.peg.fastbridge.FastBridgeFederationInformation 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)

Example 2 with FastBridgeFederationInformation

use of co.rsk.peg.fastbridge.FastBridgeFederationInformation in project rskj by rsksmart.

the class FastBridgeCompatibleBtcWallet method findRedeemDataFromScriptHash.

@Nullable
@Override
public RedeemData findRedeemDataFromScriptHash(byte[] payToScriptHash) {
    Optional<FastBridgeFederationInformation> fastBridgeFederationInformation = this.getFastBridgeFederationInformation(payToScriptHash);
    if (fastBridgeFederationInformation.isPresent()) {
        FastBridgeFederationInformation fastBridgeFederationInformationInstance = fastBridgeFederationInformation.get();
        Optional<Federation> destinationFederation = getDestinationFederation(fastBridgeFederationInformationInstance.getFederationRedeemScriptHash());
        if (!destinationFederation.isPresent()) {
            return null;
        }
        Federation destinationFederationInstance = destinationFederation.get();
        Script fedRedeemScript = destinationFederationInstance.getRedeemScript();
        RedeemScriptParser parser = RedeemScriptParserFactory.get(fedRedeemScript.getChunks());
        Script fastBridgeRedeemScript;
        if (parser.getMultiSigType() == MultiSigType.ERP_FED) {
            fastBridgeRedeemScript = FastBridgeErpRedeemScriptParser.createFastBridgeErpRedeemScript(fedRedeemScript, Sha256Hash.wrap(fastBridgeFederationInformationInstance.getDerivationHash().getBytes()));
        } else {
            fastBridgeRedeemScript = FastBridgeRedeemScriptParser.createMultiSigFastBridgeRedeemScript(fedRedeemScript, Sha256Hash.wrap(fastBridgeFederationInformationInstance.getDerivationHash().getBytes()));
        }
        return RedeemData.of(destinationFederationInstance.getBtcPublicKeys(), fastBridgeRedeemScript);
    }
    return super.findRedeemDataFromScriptHash(payToScriptHash);
}
Also used : Script(co.rsk.bitcoinj.script.Script) FastBridgeRedeemScriptParser(co.rsk.bitcoinj.script.FastBridgeRedeemScriptParser) RedeemScriptParser(co.rsk.bitcoinj.script.RedeemScriptParser) FastBridgeErpRedeemScriptParser(co.rsk.bitcoinj.script.FastBridgeErpRedeemScriptParser) FastBridgeFederationInformation(co.rsk.peg.fastbridge.FastBridgeFederationInformation) Nullable(javax.annotation.Nullable)

Example 3 with FastBridgeFederationInformation

use of co.rsk.peg.fastbridge.FastBridgeFederationInformation in project rskj by rsksmart.

the class BridgeSerializationUtils method deserializeFastBridgeFederationInformation.

public static FastBridgeFederationInformation deserializeFastBridgeFederationInformation(byte[] data, byte[] fastBridgeScriptHash) {
    if (data == null || data.length == 0) {
        return null;
    }
    RLPList rlpList = (RLPList) RLP.decode2(data).get(0);
    if (rlpList.size() != 2) {
        throw new RuntimeException(String.format("Invalid serialized Fast Bridge Federation: expected 2 value but got %d", rlpList.size()));
    }
    Keccak256 derivationHash = new Keccak256(rlpList.get(0).getRLPData());
    byte[] federationP2SH = rlpList.get(1).getRLPData();
    return new FastBridgeFederationInformation(derivationHash, federationP2SH, fastBridgeScriptHash);
}
Also used : Keccak256(co.rsk.crypto.Keccak256) RLPList(org.ethereum.util.RLPList) FastBridgeFederationInformation(co.rsk.peg.fastbridge.FastBridgeFederationInformation)

Example 4 with FastBridgeFederationInformation

use of co.rsk.peg.fastbridge.FastBridgeFederationInformation in project rskj by rsksmart.

the class BridgeStorageProviderTest method getFastBridgeFederationInformation_notFound.

@Test
public void getFastBridgeFederationInformation_notFound() {
    Repository repository = mock(Repository.class);
    byte[] fastBridgeFederationRedeemScriptHash = new byte[] { (byte) 0xaa };
    when(repository.getStorageBytes(PrecompiledContracts.BRIDGE_ADDR, DataWord.fromLongString("fastBridgeFederationInformation-" + Hex.toHexString(fastBridgeFederationRedeemScriptHash)))).thenReturn(null);
    ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class);
    when(activations.isActive(ConsensusRule.RSKIP176)).thenReturn(true);
    BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, config.getNetworkConstants().getBridgeConstants(), activations);
    Optional<FastBridgeFederationInformation> result = provider.getFastBridgeFederationInformation(fastBridgeFederationRedeemScriptHash);
    assertFalse(result.isPresent());
}
Also used : Repository(org.ethereum.core.Repository) MutableRepository(org.ethereum.db.MutableRepository) ForBlock(org.ethereum.config.blockchain.upgrades.ActivationConfig.ForBlock) FastBridgeFederationInformation(co.rsk.peg.fastbridge.FastBridgeFederationInformation) ActivationConfig(org.ethereum.config.blockchain.upgrades.ActivationConfig) ActivationConfigsForTest(org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 5 with FastBridgeFederationInformation

use of co.rsk.peg.fastbridge.FastBridgeFederationInformation in project rskj by rsksmart.

the class BridgeSerializationUtilsTest method deserializeFastBridgeFederationInformation_no_data.

@Test
public void deserializeFastBridgeFederationInformation_no_data() {
    FastBridgeFederationInformation result = BridgeSerializationUtils.deserializeFastBridgeFederationInformation(new byte[] {}, new byte[] {});
    Assert.assertNull(result);
}
Also used : FastBridgeFederationInformation(co.rsk.peg.fastbridge.FastBridgeFederationInformation) Test(org.junit.Test)

Aggregations

FastBridgeFederationInformation (co.rsk.peg.fastbridge.FastBridgeFederationInformation)26 Test (org.junit.Test)22 Keccak256 (co.rsk.crypto.Keccak256)13 ActivationConfigsForTest (org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest)11 Repository (org.ethereum.core.Repository)11 MutableRepository (org.ethereum.db.MutableRepository)11 ActivationConfig (org.ethereum.config.blockchain.upgrades.ActivationConfig)10 Script (co.rsk.bitcoinj.script.Script)9 ForBlock (org.ethereum.config.blockchain.upgrades.ActivationConfig.ForBlock)8 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)8 Context (co.rsk.bitcoinj.core.Context)7 RedeemData (co.rsk.bitcoinj.wallet.RedeemData)4 PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation (co.rsk.peg.PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation)2 PegTestUtils.createBaseRedeemScriptThatSpendsFromTheFederation (co.rsk.peg.PegTestUtils.createBaseRedeemScriptThatSpendsFromTheFederation)2 BtcLockSenderProvider (co.rsk.peg.btcLockSender.BtcLockSenderProvider)2 PeginInstructionsProvider (co.rsk.peg.pegininstructions.PeginInstructionsProvider)2 Block (org.ethereum.core.Block)2 Address (co.rsk.bitcoinj.core.Address)1 BtcTransaction (co.rsk.bitcoinj.core.BtcTransaction)1 Coin (co.rsk.bitcoinj.core.Coin)1