Search in sources :

Example 6 with Wallet

use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.

the class BridgeSupport method processFundsMigration.

private void processFundsMigration() throws IOException {
    Wallet retiringFederationWallet = getRetiringFederationWallet();
    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
        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
                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 : java.util(java.util) Hex(org.spongycastle.util.encoders.Hex) LoggerFactory(org.slf4j.LoggerFactory) RskAddress(co.rsk.core.RskAddress) Keccak256(co.rsk.crypto.Keccak256) Block(org.ethereum.core.Block) TransactionSignature(co.rsk.bitcoinj.crypto.TransactionSignature) Pair(org.apache.commons.lang3.tuple.Pair) BridgeConstants(co.rsk.config.BridgeConstants) co.rsk.bitcoinj.core(co.rsk.bitcoinj.core) PrecompiledContracts(org.ethereum.vm.PrecompiledContracts) BigInteger(java.math.BigInteger) Nullable(javax.annotation.Nullable) Wallet(co.rsk.bitcoinj.wallet.Wallet) BtcBlockStore(co.rsk.bitcoinj.store.BtcBlockStore) PanicProcessor(co.rsk.panic.PanicProcessor) ScriptChunk(co.rsk.bitcoinj.script.ScriptChunk) Logger(org.slf4j.Logger) IOException(java.io.IOException) Instant(java.time.Instant) Repository(org.ethereum.core.Repository) Collectors(java.util.stream.Collectors) SendRequest(co.rsk.bitcoinj.wallet.SendRequest) Program(org.ethereum.vm.program.Program) ScriptBuilder(co.rsk.bitcoinj.script.ScriptBuilder) Script(co.rsk.bitcoinj.script.Script) BlockStoreException(co.rsk.bitcoinj.store.BlockStoreException) VisibleForTesting(com.google.common.annotations.VisibleForTesting) RskSystemProperties(co.rsk.config.RskSystemProperties) BridgeEventLogger(co.rsk.peg.utils.BridgeEventLogger) Transaction(org.ethereum.core.Transaction) InputStream(java.io.InputStream) Wallet(co.rsk.bitcoinj.wallet.Wallet) IOException(java.io.IOException) BlockStoreException(co.rsk.bitcoinj.store.BlockStoreException)

Example 7 with Wallet

use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.

the class BridgeSupport method processReleaseRequests.

/**
 * Processes the current btc release request queue
 * and tries to build btc transactions using (and marking as spent)
 * the current active federation's utxos.
 * Newly created btc transactions are added to the btc release tx set,
 * and failed attempts are kept in the release queue for future
 * processing.
 */
private void processReleaseRequests() {
    final Wallet activeFederationWallet;
    final ReleaseRequestQueue releaseRequestQueue;
    try {
        activeFederationWallet = getActiveFederationWallet(true);
        releaseRequestQueue = provider.getReleaseRequestQueue();
    } catch (IOException e) {
        logger.error("Unexpected error accessing storage while attempting to process release requests", e);
        return;
    }
    // Releases are attempted using the currently active federation
    // wallet.
    final ReleaseTransactionBuilder txBuilder = new ReleaseTransactionBuilder(btcContext.getParams(), activeFederationWallet, getFederationAddress(), getFeePerKb(), activations);
    releaseRequestQueue.process(MAX_RELEASE_ITERATIONS, (ReleaseRequestQueue.Entry releaseRequest) -> {
        Optional<ReleaseTransactionBuilder.BuildResult> result = txBuilder.buildAmountTo(releaseRequest.getDestination(), releaseRequest.getAmount());
        // Further logging is done at the tx builder level.
        if (!result.isPresent()) {
            logger.warn("Couldn't build a release BTC tx for <{}, {}>", releaseRequest.getDestination().toBase58(), releaseRequest.getAmount());
            return false;
        }
        // We have a BTC transaction, mark the UTXOs as spent and add the tx
        // to the release set.
        List<UTXO> selectedUTXOs = result.get().getSelectedUTXOs();
        BtcTransaction generatedTransaction = result.get().getBtcTx();
        List<UTXO> availableUTXOs;
        ReleaseTransactionSet releaseTransactionSet;
        // the tx build and utxo selection, so treat as atomic)
        try {
            availableUTXOs = getActiveFederationBtcUTXOs();
            releaseTransactionSet = provider.getReleaseTransactionSet();
        } catch (IOException exception) {
            // Unexpected error accessing storage, log and fail
            logger.error(String.format("Unexpected error accessing storage while attempting to add a release BTC tx for <%s, %s>", releaseRequest.getDestination().toString(), releaseRequest.getAmount().toString()), exception);
            return false;
        }
        if (activations.isActive(ConsensusRule.RSKIP146)) {
            Keccak256 rskTxHash = releaseRequest.getRskTxHash();
            // Add the TX
            releaseTransactionSet.add(generatedTransaction, rskExecutionBlock.getNumber(), rskTxHash);
            // We shouldn't generate the event for those releases
            if (rskTxHash != null) {
                // Log the Release request
                eventLogger.logReleaseBtcRequested(rskTxHash.getBytes(), generatedTransaction, releaseRequest.getAmount());
            }
        } else {
            releaseTransactionSet.add(generatedTransaction, rskExecutionBlock.getNumber());
        }
        // Mark UTXOs as spent
        availableUTXOs.removeAll(selectedUTXOs);
        // TODO: (Ariel Mendelzon, 07/12/2017)
        // TODO: Balance adjustment assumes that change output is output with index 1.
        // TODO: This will change if we implement multiple releases per BTC tx, so
        // TODO: it would eventually need to be fixed.
        // Adjust balances in edge cases
        adjustBalancesIfChangeOutputWasDust(generatedTransaction, releaseRequest.getAmount());
        return true;
    });
}
Also used : UTXO(co.rsk.bitcoinj.core.UTXO) OneOffWhiteListEntry(co.rsk.peg.whitelist.OneOffWhiteListEntry) LockWhitelistEntry(co.rsk.peg.whitelist.LockWhitelistEntry) UnlimitedWhiteListEntry(co.rsk.peg.whitelist.UnlimitedWhiteListEntry) Wallet(co.rsk.bitcoinj.wallet.Wallet) BtcTransaction(co.rsk.bitcoinj.core.BtcTransaction) IOException(java.io.IOException) Keccak256(co.rsk.crypto.Keccak256)

Example 8 with Wallet

use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.

the class BridgeSupport method saveNewUTXOs.

/*
      Add the btcTx outputs that send btc to the federation(s) to the UTXO list
     */
private void saveNewUTXOs(BtcTransaction btcTx) throws IOException {
    // Outputs to the active federation
    List<TransactionOutput> outputsToTheActiveFederation = btcTx.getWalletOutputs(getActiveFederationWallet(false));
    for (TransactionOutput output : outputsToTheActiveFederation) {
        UTXO utxo = new UTXO(btcTx.getHash(), output.getIndex(), output.getValue(), 0, btcTx.isCoinBase(), output.getScriptPubKey());
        getActiveFederationBtcUTXOs().add(utxo);
    }
    // Outputs to the retiring federation (if any)
    Wallet retiringFederationWallet = getRetiringFederationWallet(false);
    if (retiringFederationWallet != null) {
        List<TransactionOutput> outputsToTheRetiringFederation = btcTx.getWalletOutputs(retiringFederationWallet);
        for (TransactionOutput output : outputsToTheRetiringFederation) {
            UTXO utxo = new UTXO(btcTx.getHash(), output.getIndex(), output.getValue(), 0, btcTx.isCoinBase(), output.getScriptPubKey());
            getRetiringFederationBtcUTXOs().add(utxo);
        }
    }
}
Also used : UTXO(co.rsk.bitcoinj.core.UTXO) TransactionOutput(co.rsk.bitcoinj.core.TransactionOutput) Wallet(co.rsk.bitcoinj.wallet.Wallet)

Example 9 with Wallet

use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.

the class BridgeUtils method getFederationsSpendWallet.

public static Wallet getFederationsSpendWallet(Context btcContext, List<Federation> federations, List<UTXO> utxos, boolean isFastBridgeCompatible, BridgeStorageProvider storageProvider) {
    Wallet wallet;
    if (isFastBridgeCompatible) {
        wallet = new FastBridgeCompatibleBtcWalletWithStorage(btcContext, federations, storageProvider);
    } else {
        wallet = new BridgeBtcWallet(btcContext, federations);
    }
    RskUTXOProvider utxoProvider = new RskUTXOProvider(btcContext.getParams(), utxos);
    wallet.setUTXOProvider(utxoProvider);
    federations.forEach(federation -> wallet.addWatchedAddress(federation.getAddress(), federation.getCreationTime().toEpochMilli()));
    wallet.setCoinSelector(new RskAllowUnconfirmedCoinSelector());
    return wallet;
}
Also used : Wallet(co.rsk.bitcoinj.wallet.Wallet) RskAllowUnconfirmedCoinSelector(co.rsk.peg.bitcoin.RskAllowUnconfirmedCoinSelector)

Example 10 with Wallet

use of co.rsk.bitcoinj.wallet.Wallet in project rskj by rsksmart.

the class BridgeUtils method getFederationsNoSpendWallet.

public static Wallet getFederationsNoSpendWallet(Context btcContext, List<Federation> federations, boolean isFastBridgeCompatible, BridgeStorageProvider storageProvider) {
    Wallet wallet;
    if (isFastBridgeCompatible) {
        wallet = new FastBridgeCompatibleBtcWalletWithStorage(btcContext, federations, storageProvider);
    } else {
        wallet = new BridgeBtcWallet(btcContext, federations);
    }
    federations.forEach(federation -> wallet.addWatchedAddress(federation.getAddress(), federation.getCreationTime().toEpochMilli()));
    return wallet;
}
Also used : Wallet(co.rsk.bitcoinj.wallet.Wallet)

Aggregations

Wallet (co.rsk.bitcoinj.wallet.Wallet)29 Test (org.junit.Test)11 Script (co.rsk.bitcoinj.script.Script)8 RskAddress (co.rsk.core.RskAddress)7 RskAllowUnconfirmedCoinSelector (co.rsk.peg.bitcoin.RskAllowUnconfirmedCoinSelector)7 Keccak256 (co.rsk.crypto.Keccak256)6 Context (co.rsk.bitcoinj.core.Context)5 SendRequest (co.rsk.bitcoinj.wallet.SendRequest)5 BridgeConstants (co.rsk.config.BridgeConstants)5 IOException (java.io.IOException)5 Block (org.ethereum.core.Block)5 Repository (org.ethereum.core.Repository)5 Address (co.rsk.bitcoinj.core.Address)4 BtcTransaction (co.rsk.bitcoinj.core.BtcTransaction)4 Coin (co.rsk.bitcoinj.core.Coin)4 TransactionSignature (co.rsk.bitcoinj.crypto.TransactionSignature)4 ScriptBuilder (co.rsk.bitcoinj.script.ScriptBuilder)4 ScriptChunk (co.rsk.bitcoinj.script.ScriptChunk)4 BlockStoreException (co.rsk.bitcoinj.store.BlockStoreException)4 PanicProcessor (co.rsk.panic.PanicProcessor)4