Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: tiagocs on August 11, 2020, 08:21:09 PM



Title: Selfish full node for production?
Post by: tiagocs on August 11, 2020, 08:21:09 PM
I am planning about launching a bandwidth-intensive service. My application will be running on a server with a full node, and I was wondering if I could disable peers from downloading historical blocks from my node to optimize the bandwidth for my application. Actually, stopping them from downloading any block from my node would also work :P

I know many of you will not like this idea because it's selfish, but I already run a second, sometimes third, node. I am aware of the "blocksonly" mode, but it's not an option as I need a mempool.


Title: Re: Selfish full node for production?
Post by: JuleAdka on August 11, 2020, 09:38:42 PM
Maybe I'm wrong, but if you change the node services for NETWORK_LIMITED(node don't send historical blocks), the peers will not request blocks to you. It's the only way that I know for you case.


Title: Re: Selfish full node for production?
Post by: gmaxwell on August 11, 2020, 11:49:36 PM
You can set an amount of upload limit per day very low with -maxuploadtarget.

You can also reduce your maximum connection count, which will reduce traffic a lot.


You can also run a pruned node, which will cause you to not serve historical blocks at all.  This is the best.  I'm not sure if there is a flag to set node-limited while still actually having all the blocks... there should be. (perhaps setting pruning with an absurdly high pruning limit is sufficient).


There are plenty of nodes on the network serving historical blocks, it's not particularly selfish to not do so. 


Title: Re: Selfish full node for production?
Post by: ABCbits on August 12, 2020, 12:27:17 PM
The lazy way are :
1. Disable incoming connection
2. Run your node behind NAT (without configure port forwarding)

I wouldn't say it's selfish since there are some people who only use SPV wallet or Bitcoin Core, but are behind NAT without knowledge about port forwarding.


Title: Re: Selfish full node for production?
Post by: tiagocs on August 12, 2020, 02:55:39 PM
Thank you for all the suggestions. I think I pulled together those that work best for. Here is how I am setting up my bitcoin.conf:

Code:
maxconnections=8 // no more than the 8 outbound connections my node will attempt
addnode=123.123.123.123 // my external node that I am sure it will always be up
addnode-122.122.122.122 // some node geographically close to me with an up-to-date block height (maybe repeat this step)

peerbloomfilters=0 // disable SPV clients from doing block filtering
blockfilterindex=0 // I think this is unnecessary because it's the default, but just making sure


Setting a low with -maxuploadtarget won't work for me because my application will broadcast many transactions (possibly new to the network), so it's very important that these broadcasts are done properly.
I also don't want to prune because I need the whole tx history.

@JuleAdka suggestion seems interesting. I took a look at BIP 159 (https://github.com/bitcoin/bips/blob/master/bip-0159.mediawiki) which introduced NODE_NETWORK_LIMITED. Disabling NODE_NETWORK might be a good way to make sure nobody tries to download historical blocks from my node. Is there a way to disable this service flag? Searched through the options and didn't find a way to do it (bitcoind --help | grep "service").


Title: Re: Selfish full node for production?
Post by: gmaxwell on August 12, 2020, 04:26:00 PM
maxconnections=8 // no more than the 8 outbound connections my node will attempt
That will work but disabling p2p listening would be better (also not allow inbound but will be more secure).

Quote
Setting a low with -maxuploadtarget won't work for me because my application will broadcast many transactions (possibly new to the network), so it's very important that these broadcasts are done properly.
Yes it would. maxuploadtarget only restricts fetching historical blocks, it won't restrict anything about you sending transactions.

Quote
@JuleAdka suggestion seems interesting. I took a look at BIP 159 (https://github.com/bitcoin/bips/blob/master/bip-0159.mediawiki) which introduced NODE_NETWORK_LIMITED. Disabling NODE_NETWORK might be a good way to make sure nobody tries to download historical blocks from my node. Is there a way to disable this service flag? Searched through the options and didn't find a way to do it (bitcoind --help | grep "service").
Yes, enable pruning. You can set the pruning limit so high that nothing actually gets pruned, but you'll still signal yourself as pruned to the network. An option should probably get added to do this more directly, you should open a feature request for a "-nodelimited=1" option.

What you signal is mostly moot however, if you're not even listening for connections from outside.


Title: Re: Selfish full node for production?
Post by: JuleAdka on August 12, 2020, 08:12:13 PM
Thank you for all the suggestions. I think I pulled together those that work best for. Here is how I am setting up my bitcoin.conf:

Code:
maxconnections=8 // no more than the 8 outbound connections my node will attempt
addnode=123.123.123.123 // my external node that I am sure it will always be up
addnode-122.122.122.122 // some node geographically close to me with an up-to-date block height (maybe repeat this step)

peerbloomfilters=0 // disable SPV clients from doing block filtering
blockfilterindex=0 // I think this is unnecessary because it's the default, but just making sure


Setting a low with -maxuploadtarget won't work for me because my application will broadcast many transactions (possibly new to the network), so it's very important that these broadcasts are done properly.
I also don't want to prune because I need the whole tx history.

@JuleAdka suggestion seems interesting. I took a look at BIP 159 (https://github.com/bitcoin/bips/blob/master/bip-0159.mediawiki) which introduced NODE_NETWORK_LIMITED. Disabling NODE_NETWORK might be a good way to make sure nobody tries to download historical blocks from my node. Is there a way to disable this service flag? Searched through the options and didn't find a way to do it (bitcoind --help | grep "service").

You have way to compile the code? If yes, you can open the "init.cpp" file, and change the line 878 (Core-0.20.0)
from:
ServiceFlags nLocalServices = ServiceFlags(NODE_NETWORK | NODE_NETWORK_LIMITED);
to:
ServiceFlags nLocalServices = ServiceFlags(NODE_NETWORK_LIMITED);
But, you probably had seen in BIP159 that your node still will send the most recent blocks (the BIP says 288)

Edit: Newbie question, how to add code in the wiki's markdown?


Title: Re: Selfish full node for production?
Post by: tiagocs on August 12, 2020, 09:32:39 PM
Yes it would. maxuploadtarget only restricts fetching historical blocks, it won't restrict anything about you sending transactions.
That's great, I think I will use it then.

Yes, enable pruning. You can set the pruning limit so high that nothing actually gets pruned, but you'll still signal yourself as pruned to the network. An option should probably get added to do this more directly, you should open a feature request for a "-nodelimited=1" option.
I am using txindex and according to the command line help, it's not compatible with prunning.

What you signal is mostly moot however, if you're not even listening for connections from outside.
Wouldn't my outbout 8 peers receive whatever I broadcast with sendrawtransaction? I will set maxconnections to 20 then, just to be safe.

Edit: Newbie question, how to add code in the wiki's markdown?
Is this what you mean? https://i.imgur.com/JoceIlN.png


Title: Re: Selfish full node for production?
Post by: gmaxwell on August 13, 2020, 12:28:52 AM
What you signal is mostly moot however, if you're not even listening for connections from outside.
Wouldn't my outbout 8 peers receive whatever I broadcast with sendrawtransaction? I will set maxconnections to 20 then, just to be safe.
I mean it doesn't matter if you are node-limited or not.  Nodes that you connect out to will not request historical blocks from you unless they're weird and modified. This is done specifically to avoid burdening users on limited connections behind NAT with hundreds of gigabytes of block requests per month.  You only end up serving historical blocks if you accept incoming connections.