Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot broadcast pending transactions #17

Open
Yuiki opened this issue Feb 3, 2018 · 8 comments
Open

Cannot broadcast pending transactions #17

Yuiki opened this issue Feb 3, 2018 · 8 comments

Comments

@Yuiki
Copy link

Yuiki commented Feb 3, 2018

Sometimes I cannot broadcast pending transactions because active peers size won't be larger than the value returned by PeerGroup#getMinBroadcastTransacions.
So, I want to call PeerGroup#setMinBroadcastTransactions before broadcasting pending transactions on startup...

@Danconnolly
Copy link
Collaborator

Is this on testnet? It can be a problem on testnet but shouldnt be a problem on the main network unless you are changing the number of peers to connect to. But yes, calling setMinBroadcastTransactions is an option. If you decrease it then the result is that you will have less assurance that the transaction has been received by the network.

@Yuiki
Copy link
Author

Yuiki commented Feb 4, 2018

Yes, on testnet. However, calling setMinBroadcastTransactions after WalletAppKit#onSetupCompleted has no meaning because this library broadcasts pending transactions before onSetupCompleted callback...

@HashEngineering
Copy link
Collaborator

This is the basic idea of how broadcasting works.

The default value for the PeerGroup.minBroadcastConnections is Zero (0).

Peer.getMinBroadcastConnections() will return the minBroadcastConnections if it was set with setMinBroadcastTransactions, otherwise it will return a number that is 80% of the maximum connections.

PeerGroup.setMaxConnections() will set this maximum value. Bitcoin Cash Wallet, my android app, sets the maximum number of connections to 4 or 6 based on the amount of memory the device has.

In my case, most devices will have 6 peers maximum, so the requirement to broadcast is 5 (80% of 6).

When broadcasting, it will send the transaction to one more than half of the peers. It will wait for the other peers to send "inv" messages with the transaction id, which tells bitcoinj that the transaction was broadcast sucessfully.

In my app, I have also noticed that when the app starts, it only requires 1 peer to broadcast a transaction, perhaps because the setMaxConnections() hasn't been called yet and the minBroadcastConnections is still zero.

Today, I was working on my app, both testnet and mainnet and I am getting plenty of connections to send and I am using bitcoinj-cash 0.14.5.2.

In your case, it may be that your setMaxConnections() is set too high. Are you using WalletAppKit?

@Yuiki
Copy link
Author

Yuiki commented Feb 5, 2018

Yes, I use WalletAppKit. WalletAppKit calls vPeerGroup.addPearDiscovery. setMaxConnections(DEFAULT_CONNECTIONS) called in addPeerDiscovery. DEFAULT_CONNECTIONS is 12, but it is final, so I cannot modify the value.

My device sometimes meets the requirement(12* 0.8 = 10 peers), but sometimes doesn't meet(active peer size is less than 10 for a long time).

@HashEngineering
Copy link
Collaborator

That will explain your issues as the app requires too many peers considering how many are being connected. My app doesn't use WalletAppKit, so it handles these aspects on its own with greater control.

@Yuiki
Copy link
Author

Yuiki commented Feb 17, 2018

I'll use bitcoinj.cash without WalletAppKit! Thank you for detailed information.

@kodmanyagha
Copy link

How can I use bitcoincashj without wallet app kit? Is there a document for this?

@HashEngineering
Copy link
Collaborator

Documentation is in the source code or this site: https://bitcoinj.github.io/javadoc/0.14.6/

From https://bitcoinj.github.io/javadoc/0.14.6/org/bitcoinj/kits/WalletAppKit.html:

public class WalletAppKit
extends com.google.common.util.concurrent.AbstractIdleService
Utility class that wraps the boilerplate needed to set up a new SPV bitcoinj app. Instantiate it with a directory and file prefix, optionally configure a few things, then use startAsync and optionally awaitRunning. The object will construct and configure a BlockChain, SPVBlockStore, Wallet and PeerGroup. Depending on the value of the blockingStartup property, startup will be considered complete once the block chain has fully synchronized, so it can take a while.

To add listeners and modify the objects that are constructed, you can either do that by overriding the onSetupCompleted() method (which will run on a background thread) and make your changes there, or by waiting for the service to start and then accessing the objects from wherever you want. However, you cannot access the objects this class creates until startup is complete.

For example:

class MyWalletAppKit extends WalletAppKit
    {
        MyWalletAppKit(NetworkParameters params, File file, String filePrefix)
        {
            super(params, file, filePrefix);
        }

        @Override
        protected void onSetupCompleted()
        {
            peerGroup().setMaxConnections(6);
            //set other parameter here...
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants