Search in sources :

Example 1 with ConfidenceType

use of org.bitcoinj.core.TransactionConfidence.ConfidenceType in project bitcoin-wallet by bitcoin-wallet.

the class SendCoinsFragment method onCreate.

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.fragmentManager = getChildFragmentManager();
    setHasOptionsMenu(true);
    walletActivityViewModel = new ViewModelProvider(activity).get(AbstractWalletActivityViewModel.class);
    walletActivityViewModel.wallet.observe(this, wallet -> updateView());
    viewModel = new ViewModelProvider(this).get(SendCoinsViewModel.class);
    viewModel.addressBook.observe(this, addressBook -> updateView());
    if (config.isEnableExchangeRates()) {
        viewModel.exchangeRate.observe(this, exchangeRate -> {
            final SendCoinsViewModel.State state = viewModel.state;
            if (state == null || state.compareTo(SendCoinsViewModel.State.INPUT) <= 0)
                amountCalculatorLink.setExchangeRate(exchangeRate != null ? exchangeRate.exchangeRate() : null);
        });
    }
    viewModel.dynamicFees.observe(this, dynamicFees -> {
        updateView();
        handler.post(dryrunRunnable);
    });
    application.blockchainState.observe(this, blockchainState -> updateView());
    viewModel.balance.observe(this, coin -> activity.invalidateOptionsMenu());
    viewModel.progress.observe(this, new ProgressDialogFragment.Observer(fragmentManager));
    viewModel.sentTransaction.observe(this, transaction -> {
        if (viewModel.state == SendCoinsViewModel.State.SENDING) {
            final TransactionConfidence confidence = transaction.getConfidence();
            final ConfidenceType confidenceType = confidence.getConfidenceType();
            final int numBroadcastPeers = confidence.numBroadcastPeers();
            if (confidenceType == ConfidenceType.DEAD)
                setState(SendCoinsViewModel.State.FAILED);
            else if (numBroadcastPeers > 1 || confidenceType == ConfidenceType.BUILDING)
                setState(SendCoinsViewModel.State.SENT);
        }
        updateView();
    });
    bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    backgroundThread = new HandlerThread("backgroundThread", Process.THREAD_PRIORITY_BACKGROUND);
    backgroundThread.start();
    backgroundHandler = new Handler(backgroundThread.getLooper());
    if (savedInstanceState == null) {
        final Intent intent = activity.getIntent();
        final String action = intent.getAction();
        final Uri intentUri = intent.getData();
        final String scheme = intentUri != null ? intentUri.getScheme() : null;
        final String mimeType = intent.getType();
        if ((Intent.ACTION_VIEW.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) && intentUri != null && "bitcoin".equals(scheme)) {
            initStateFromBitcoinUri(intentUri);
        } else if ((NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) && PaymentProtocol.MIMETYPE_PAYMENTREQUEST.equals(mimeType)) {
            final NdefMessage ndefMessage = (NdefMessage) intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)[0];
            final byte[] ndefMessagePayload = Nfc.extractMimePayload(PaymentProtocol.MIMETYPE_PAYMENTREQUEST, ndefMessage);
            initStateFromPaymentRequest(mimeType, ndefMessagePayload);
        } else if ((Intent.ACTION_VIEW.equals(action)) && PaymentProtocol.MIMETYPE_PAYMENTREQUEST.equals(mimeType)) {
            final byte[] paymentRequest = BitcoinIntegration.paymentRequestFromIntent(intent);
            if (intentUri != null)
                initStateFromIntentUri(mimeType, intentUri);
            else if (paymentRequest != null)
                initStateFromPaymentRequest(mimeType, paymentRequest);
            else
                throw new IllegalArgumentException();
        } else if (intent.hasExtra(SendCoinsActivity.INTENT_EXTRA_PAYMENT_INTENT)) {
            initStateFromIntentExtras(intent.getExtras());
        } else {
            updateStateFrom(PaymentIntent.blank());
        }
    }
}
Also used : ProgressDialogFragment(de.schildbach.wallet.ui.ProgressDialogFragment) Handler(android.os.Handler) NdefMessage(android.nfc.NdefMessage) PaymentIntent(de.schildbach.wallet.data.PaymentIntent) Intent(android.content.Intent) Uri(android.net.Uri) ConfidenceType(org.bitcoinj.core.TransactionConfidence.ConfidenceType) HandlerThread(android.os.HandlerThread) AbstractWalletActivityViewModel(de.schildbach.wallet.ui.AbstractWalletActivityViewModel) TransactionConfidence(org.bitcoinj.core.TransactionConfidence) ViewModelProvider(androidx.lifecycle.ViewModelProvider)

Example 2 with ConfidenceType

use of org.bitcoinj.core.TransactionConfidence.ConfidenceType in project bitcoin-wallet by bitcoin-wallet.

the class SweepWalletFragment method onCreate.

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.fragmentManager = getChildFragmentManager();
    setHasOptionsMenu(true);
    if (!Constants.ENABLE_SWEEP_WALLET)
        throw new IllegalStateException("ENABLE_SWEEP_WALLET is disabled");
    walletActivityViewModel = new ViewModelProvider(activity).get(AbstractWalletActivityViewModel.class);
    walletActivityViewModel.wallet.observe(this, wallet -> updateView());
    viewModel = new ViewModelProvider(this).get(SweepWalletViewModel.class);
    viewModel.getDynamicFees().observe(this, dynamicFees -> updateView());
    viewModel.progress.observe(this, new ProgressDialogFragment.Observer(fragmentManager));
    viewModel.privateKeyToSweep.observe(this, privateKeyToSweep -> updateView());
    viewModel.walletToSweep.observe(this, walletToSweep -> {
        if (walletToSweep != null) {
            balanceView.setVisibility(View.VISIBLE);
            final MonetaryFormat btcFormat = config.getFormat();
            final MonetarySpannable balanceSpannable = new MonetarySpannable(btcFormat, walletToSweep.getBalance(BalanceType.ESTIMATED));
            balanceSpannable.applyMarkup(null, null);
            final SpannableStringBuilder balance = new SpannableStringBuilder(balanceSpannable);
            balance.insert(0, ": ");
            balance.insert(0, getString(R.string.sweep_wallet_fragment_balance));
            balanceView.setText(balance);
        } else {
            balanceView.setVisibility(View.GONE);
        }
        updateView();
    });
    viewModel.sentTransaction.observe(this, transaction -> {
        if (viewModel.state == SweepWalletViewModel.State.SENDING) {
            final TransactionConfidence confidence = transaction.getConfidence();
            final ConfidenceType confidenceType = confidence.getConfidenceType();
            final int numBroadcastPeers = confidence.numBroadcastPeers();
            if (confidenceType == ConfidenceType.DEAD)
                setState(SweepWalletViewModel.State.FAILED);
            else if (numBroadcastPeers > 1 || confidenceType == ConfidenceType.BUILDING)
                setState(SweepWalletViewModel.State.SENT);
        }
        updateView();
    });
    viewModel.showDialog.observe(this, new DialogEvent.Observer(activity));
    viewModel.showDialogWithRetryRequestBalance.observe(this, new DialogEvent.Observer(activity) {

        @Override
        protected void onBuildButtons(final DialogBuilder dialog) {
            dialog.setPositiveButton(R.string.button_retry, (d, which) -> requestWalletBalance());
            dialog.setNegativeButton(R.string.button_dismiss, null);
        }
    });
    backgroundThread = new HandlerThread("backgroundThread", Process.THREAD_PRIORITY_BACKGROUND);
    backgroundThread.start();
    backgroundHandler = new Handler(backgroundThread.getLooper());
    if (savedInstanceState == null) {
        final Intent intent = activity.getIntent();
        if (intent.hasExtra(SweepWalletActivity.INTENT_EXTRA_KEY)) {
            final PrefixedChecksummedBytes privateKeyToSweep = (PrefixedChecksummedBytes) intent.getSerializableExtra(SweepWalletActivity.INTENT_EXTRA_KEY);
            viewModel.privateKeyToSweep.setValue(privateKeyToSweep);
            // delay until fragment is resumed
            handler.post(maybeDecodeKeyRunnable);
        }
    }
}
Also used : MonetarySpannable(de.schildbach.wallet.util.MonetarySpannable) Bundle(android.os.Bundle) DumpedPrivateKey(org.bitcoinj.core.DumpedPrivateKey) Transaction(org.bitcoinj.core.Transaction) PackageManager(android.content.pm.PackageManager) Coin(org.bitcoinj.core.Coin) WalletTransaction(org.bitcoinj.wallet.WalletTransaction) LoggerFactory(org.slf4j.LoggerFactory) ScanActivity(de.schildbach.wallet.ui.scan.ScanActivity) AbstractWalletActivityViewModel(de.schildbach.wallet.ui.AbstractWalletActivityViewModel) Process(android.os.Process) NetworkParameters(org.bitcoinj.core.NetworkParameters) PrefixedChecksummedBytes(org.bitcoinj.core.PrefixedChecksummedBytes) SendRequest(org.bitcoinj.wallet.SendRequest) Handler(android.os.Handler) Map(java.util.Map) Fragment(androidx.fragment.app.Fragment) View(android.view.View) Button(android.widget.Button) R(de.schildbach.wallet.R) Configuration(de.schildbach.wallet.Configuration) Constants(de.schildbach.wallet.Constants) PaymentIntent(de.schildbach.wallet.data.PaymentIntent) BalanceType(org.bitcoinj.wallet.Wallet.BalanceType) ConfidenceType(org.bitcoinj.core.TransactionConfidence.ConfidenceType) Set(java.util.Set) ComparisonChain(com.google.common.collect.ComparisonChain) ViewGroup(android.view.ViewGroup) Preconditions.checkState(androidx.core.util.Preconditions.checkState) ECKey(org.bitcoinj.core.ECKey) TextView(android.widget.TextView) Nullable(androidx.annotation.Nullable) TransactionsAdapter(de.schildbach.wallet.ui.TransactionsAdapter) TransactionOutput(org.bitcoinj.core.TransactionOutput) UTXO(org.bitcoinj.core.UTXO) Context(android.content.Context) TransactionConfidence(org.bitcoinj.core.TransactionConfidence) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Wallet(org.bitcoinj.wallet.Wallet) Intent(android.content.Intent) HashMap(java.util.HashMap) TreeSet(java.util.TreeSet) MenuItem(android.view.MenuItem) AnimationUtils(android.view.animation.AnimationUtils) ProgressDialogFragment(de.schildbach.wallet.ui.ProgressDialogFragment) SpannableStringBuilder(android.text.SpannableStringBuilder) VerificationException(org.bitcoinj.core.VerificationException) MenuInflater(android.view.MenuInflater) Menu(android.view.Menu) DialogEvent(de.schildbach.wallet.ui.DialogEvent) Sha256Hash(org.bitcoinj.core.Sha256Hash) BIP38PrivateKey(org.bitcoinj.crypto.BIP38PrivateKey) FragmentManager(androidx.fragment.app.FragmentManager) TransactionOutPoint(org.bitcoinj.core.TransactionOutPoint) Logger(org.slf4j.Logger) ViewModelProvider(androidx.lifecycle.ViewModelProvider) LayoutInflater(android.view.LayoutInflater) MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) Threading(org.bitcoinj.utils.Threading) AbstractWalletActivity(de.schildbach.wallet.ui.AbstractWalletActivity) DialogBuilder(de.schildbach.wallet.ui.DialogBuilder) HandlerThread(android.os.HandlerThread) TransactionInput(org.bitcoinj.core.TransactionInput) StringInputParser(de.schildbach.wallet.ui.InputParser.StringInputParser) WalletApplication(de.schildbach.wallet.WalletApplication) Comparator(java.util.Comparator) Activity(android.app.Activity) EditText(android.widget.EditText) MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) PrefixedChecksummedBytes(org.bitcoinj.core.PrefixedChecksummedBytes) ProgressDialogFragment(de.schildbach.wallet.ui.ProgressDialogFragment) Handler(android.os.Handler) PaymentIntent(de.schildbach.wallet.data.PaymentIntent) Intent(android.content.Intent) MonetarySpannable(de.schildbach.wallet.util.MonetarySpannable) TransactionOutPoint(org.bitcoinj.core.TransactionOutPoint) ConfidenceType(org.bitcoinj.core.TransactionConfidence.ConfidenceType) DialogEvent(de.schildbach.wallet.ui.DialogEvent) HandlerThread(android.os.HandlerThread) AbstractWalletActivityViewModel(de.schildbach.wallet.ui.AbstractWalletActivityViewModel) DialogBuilder(de.schildbach.wallet.ui.DialogBuilder) TransactionConfidence(org.bitcoinj.core.TransactionConfidence) SpannableStringBuilder(android.text.SpannableStringBuilder) ViewModelProvider(androidx.lifecycle.ViewModelProvider)

Example 3 with ConfidenceType

use of org.bitcoinj.core.TransactionConfidence.ConfidenceType in project bitcoin-wallet by bitcoin-wallet.

the class BlockchainService method observeLiveDatasThatAreDependentOnWalletAndBlockchain.

private void observeLiveDatasThatAreDependentOnWalletAndBlockchain() {
    final NewTransactionLiveData newTransaction = new NewTransactionLiveData(wallet.getValue());
    newTransaction.observe(this, tx -> {
        final Wallet wallet = BlockchainService.this.wallet.getValue();
        postDelayedStopSelf(5 * DateUtils.MINUTE_IN_MILLIS);
        final Coin amount = tx.getValue(wallet);
        if (amount.isPositive()) {
            final Address address = WalletUtils.getWalletAddressOfReceived(tx, wallet);
            final ConfidenceType confidenceType = tx.getConfidence().getConfidenceType();
            final boolean replaying = blockChain.getBestChainHeight() < config.getBestChainHeightEver();
            final boolean isReplayedTx = confidenceType == ConfidenceType.BUILDING && replaying;
            if (!isReplayedTx)
                notifyCoinsReceived(address, amount, tx.getTxId());
        }
    });
    impediments = new ImpedimentsLiveData(application);
    impediments.observe(this, new Observer<Set<Impediment>>() {

        @Override
        public void onChanged(final Set<Impediment> impediments) {
            if (impediments.isEmpty() && peerGroup == null && Constants.ENABLE_BLOCKCHAIN_SYNC)
                startup();
            else if (!impediments.isEmpty() && peerGroup != null)
                shutdown();
            broadcastBlockchainState();
        }

        private void startup() {
            final Wallet wallet = BlockchainService.this.wallet.getValue();
            // consistency check
            final int walletLastBlockSeenHeight = wallet.getLastBlockSeenHeight();
            final int bestChainHeight = blockChain.getBestChainHeight();
            if (walletLastBlockSeenHeight != -1 && walletLastBlockSeenHeight != bestChainHeight) {
                final String message = "wallet/blockchain out of sync: " + walletLastBlockSeenHeight + "/" + bestChainHeight;
                log.error(message);
                CrashReporter.saveBackgroundTrace(new RuntimeException(message), application.packageInfo());
            }
            final Configuration.SyncMode syncMode = config.getSyncMode();
            peerGroup = new PeerGroup(Constants.NETWORK_PARAMETERS, blockChain);
            log.info("creating {}, sync mode: {}", peerGroup, syncMode);
            // recursive implementation causes StackOverflowError
            peerGroup.setDownloadTxDependencies(0);
            peerGroup.addWallet(wallet);
            peerGroup.setBloomFilteringEnabled(syncMode == Configuration.SyncMode.CONNECTION_FILTER);
            peerGroup.setUserAgent(Constants.USER_AGENT, application.packageInfo().versionName);
            peerGroup.addConnectedEventListener(peerConnectivityListener);
            peerGroup.addDisconnectedEventListener(peerConnectivityListener);
            final int maxConnectedPeers = application.maxConnectedPeers();
            final Set<HostAndPort> trustedPeers = config.getTrustedPeers();
            final boolean trustedPeerOnly = config.isTrustedPeersOnly();
            peerGroup.setMaxConnections(trustedPeerOnly ? 0 : maxConnectedPeers);
            peerGroup.setConnectTimeoutMillis(Constants.PEER_TIMEOUT_MS);
            peerGroup.setPeerDiscoveryTimeoutMillis(Constants.PEER_DISCOVERY_TIMEOUT_MS);
            peerGroup.setStallThreshold(20, Block.HEADER_SIZE * 10);
            final ResolveDnsTask resolveDnsTask = new ResolveDnsTask(backgroundHandler) {

                @Override
                protected void onSuccess(final HostAndPort hostAndPort, final InetSocketAddress socketAddress) {
                    log.info("trusted peer '{}' resolved to {}", hostAndPort, socketAddress.getAddress().getHostAddress());
                    if (socketAddress != null) {
                        peerGroup.addAddress(new PeerAddress(Constants.NETWORK_PARAMETERS, socketAddress), 10);
                        if (peerGroup.getMaxConnections() > maxConnectedPeers)
                            peerGroup.setMaxConnections(maxConnectedPeers);
                    }
                }

                @Override
                protected void onUnknownHost(final HostAndPort hostAndPort) {
                    log.info("trusted peer '{}' unknown host", hostAndPort);
                }
            };
            for (final HostAndPort trustedPeer : trustedPeers) resolveDnsTask.resolve(trustedPeer);
            if (trustedPeerOnly) {
                log.info("trusted peers only – not adding any random nodes from the P2P network");
            } else {
                log.info("adding random peers from the P2P network");
                if (syncMode == Configuration.SyncMode.CONNECTION_FILTER)
                    peerGroup.setRequiredServices(VersionMessage.NODE_BLOOM | VersionMessage.NODE_WITNESS);
                else
                    peerGroup.setRequiredServices(VersionMessage.NODE_WITNESS);
            }
            // start peergroup
            log.info("starting {} asynchronously", peerGroup);
            peerGroup.startAsync();
            peerGroup.startBlockChainDownload(blockchainDownloadListener);
            postDelayedStopSelf(DateUtils.MINUTE_IN_MILLIS / 2);
        }

        private void shutdown() {
            final Wallet wallet = BlockchainService.this.wallet.getValue();
            peerGroup.removeDisconnectedEventListener(peerConnectivityListener);
            peerGroup.removeConnectedEventListener(peerConnectivityListener);
            peerGroup.removeWallet(wallet);
            log.info("stopping {} asynchronously", peerGroup);
            peerGroup.stopAsync();
            peerGroup = null;
        }
    });
}
Also used : EnumSet(java.util.EnumSet) Set(java.util.Set) InetSocketAddress(java.net.InetSocketAddress) Address(org.bitcoinj.core.Address) PeerAddress(org.bitcoinj.core.PeerAddress) Wallet(org.bitcoinj.wallet.Wallet) InetSocketAddress(java.net.InetSocketAddress) PeerGroup(org.bitcoinj.core.PeerGroup) ResolveDnsTask(de.schildbach.wallet.ui.preference.ResolveDnsTask) Impediment(de.schildbach.wallet.service.BlockchainState.Impediment) Coin(org.bitcoinj.core.Coin) ConfidenceType(org.bitcoinj.core.TransactionConfidence.ConfidenceType) HostAndPort(com.google.common.net.HostAndPort) PeerAddress(org.bitcoinj.core.PeerAddress)

Aggregations

ConfidenceType (org.bitcoinj.core.TransactionConfidence.ConfidenceType)3 Intent (android.content.Intent)2 Handler (android.os.Handler)2 HandlerThread (android.os.HandlerThread)2 ViewModelProvider (androidx.lifecycle.ViewModelProvider)2 PaymentIntent (de.schildbach.wallet.data.PaymentIntent)2 AbstractWalletActivityViewModel (de.schildbach.wallet.ui.AbstractWalletActivityViewModel)2 ProgressDialogFragment (de.schildbach.wallet.ui.ProgressDialogFragment)2 TransactionConfidence (org.bitcoinj.core.TransactionConfidence)2 Activity (android.app.Activity)1 Context (android.content.Context)1 PackageManager (android.content.pm.PackageManager)1 Uri (android.net.Uri)1 NdefMessage (android.nfc.NdefMessage)1 Bundle (android.os.Bundle)1 Process (android.os.Process)1 SpannableStringBuilder (android.text.SpannableStringBuilder)1 LayoutInflater (android.view.LayoutInflater)1 Menu (android.view.Menu)1 MenuInflater (android.view.MenuInflater)1