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

Add a switch to allow running in a pruned state #4481

Closed
wants to merge 2 commits into from

Conversation

rdponticelli
Copy link
Contributor

To avoid stalling the downloads of other peers, we disconnect those
who ask us for a block we don't have anymore.

@petertodd
Copy link
Contributor

I think this is acceptable so long as you add a "-allowpruned" option that disables the "we have all blocks" check on startup and unsets the NODE_NETWORK service bit. (meaning we act like a SPV client)

You could argue with that you might as well not disconnect peers that ask for blocks you don't have, as you aren't advertising that you have any blocks at all. That might be useful for some types of local usage, and probably does no harm.

@laanwj
Copy link
Member

laanwj commented Jul 8, 2014

Agree with @petertodd here. If you don't run a full node, you should not have it advertise NODE_NETWORK. The P2P protocol at this point does not support advertising availability of only ranges of blocks, and disconnecting anyone that happens to request a block that's missing seems very crude.

Also: -allowpruned should imply -disablewallet, as the wallet currently relies on being able to rescan the blocks on disk, for example on importkey or importwallet.

@petertodd
Copy link
Contributor

@laanwj Good point. You could make pruning just disable some wallet functionality, but disabling all wallet functionality is simpler for now - we might not have the wallet in the future anyway.

@rdponticelli
Copy link
Contributor Author

Thanks for the feedback. Pull updated, addressing the input.

@laanwj
Copy link
Member

laanwj commented Jul 9, 2014

I like the idea of an UTXO-only, non-archival node.

  • Excluding the wallet, we still need to test the rest of the RPC API for robustness against missing block data. How does this interact with gettransaction (w/ possible txindex), for example?
  • Ideally this would be accompanied with an option to not write blocks to disk at all. I think the current expectation is that some external program does the 'pruning'?

@rdponticelli
Copy link
Contributor Author

@ashleyholman: I guess we should try and test fully what happens unsetting the flag, but that looks like the sensible thing to do.

@gmaxwell
Copy link
Contributor

It should also check that so much hasn't been removed that it can't survive realistic reorganizations... a bunch of nodes that just refuse to reorg would be fairly harmful to the network (not to mention their users!). I'd suggest the check go back 288 blocks from tip since thats our default for the extensive checkblocks.

This also needs at least a modest testplan to check that none of the exposed RPCs will crash, and that any that would crash are disabled. It should also be made incompatible with txindex.

@gmaxwell
Copy link
Contributor

We may also want to leave this out of usage until it's had a fair amount of testing (e.g. in the first release with it)... esp I'd worry that there may be additional network triggerable misbehavior from places where this violates assumptions.

@gmaxwell
Copy link
Contributor

So after giving this more though, instead of allowpruned— why not just go all the way and have a pruned=1 ... with the logic that if our validated height is >100k and a blockfiles highest block is <tip-288, just delete the block file? This would allow you to sync up without much free disk space (the first 119k blocks are small and fit in the first block file).

@gmaxwell
Copy link
Contributor

(Sipa pointed out to me that the rational for the 100k limit was not obvious. The reason I proposed that was because without it if someone gave you a 400 block reorg during the very early initial block download you would not recover. The 100k limit gets the difficulty to a non-completely-trivial level, and is also few enough that its still in a single block file, so there would be no peak usage increase. Better to have a total-work check, but that would probably need headers first in order to be easy to implement).

@rdponticelli
Copy link
Contributor Author

So, there are several possible modes of operation after we allow pruning. @laanwj's utxosonly, @gmaxwell's autoprune are both interesting, and there could be more...

Should I modify this patch to allow setting them as options, or would that add too much unneeded complexity?

@gmaxwell
Copy link
Contributor

UTXO only cannot be done without substantial work because the node would be unable to reorganize.

@rdponticelli
Copy link
Contributor Author

Yeah, obviously autoprune is a way lower hanging fruit.

Maybe after #4468 utxoonly can be possible, but yes, at a significantly cost.

@laanwj
Copy link
Member

laanwj commented Jul 11, 2014

Right, I did not think about reorganizations. A node that would fall over on even a small reorganization would be pointless. And storing a few blocks isn't a problem.

@gmaxwell's idea about keeping only the recent N>288 blocks when height>100k sounds great, and is how auto-pruning should work.

@gmaxwell
Copy link
Contributor

WRT UTXO-only, we'd also need to add code to hash the undo files, and add network code to fetch them (and make the undo datastructure normative along the way)... Or, just don't delete the undo files but this is unattractive since there is currently about 2gb of undo data.

So I think for now we should just do the autopruned which disables the wallet and txindex and keeps enough blocks that reorg failure is very unlikely. Then we can think about the above steps with the undo data, along with keeping the ability to remain acting as a node-network.

@wtogami
Copy link
Contributor

wtogami commented Jul 12, 2014

Shouldn't this also disable UPNP as the only reason it is used is to allow incoming connections to possibly sync from your node?

@petertodd
Copy link
Contributor

I wouldn't bother, as we'll want to let nodes advertise useful services beyond the blockchain, e.g. tx relaying.

On 12 July 2014 10:28:41 BST, Warren Togami notifications@github.com wrote:

Shouldn't this also disable UPNP as the only reason it is used is to
allow incoming connections to possibly sync from your node?


Reply to this email directly or view it on GitHub:
#4481 (comment)

@gmaxwell
Copy link
Contributor

We don't want to disable listening or UPNP because you may want to use the node with p2pool or the like, but we should probably suppress address messages when we're not node-network. I think that should just wait until another pull though.

@petertodd
Copy link
Contributor

@gmaxwell Sounds good to me.

On 12 July 2014 13:32:58 GMT+01:00, Gregory Maxwell notifications@github.com wrote:

We don't want to disable listening or UPNP because you may want to use
the node with p2pool or the like, but we should probably suppress
address messages when we're not node-network. I think that should just
wait until another pull though.


Reply to this email directly or view it on GitHub:
#4481 (comment)

@jgarzik
Copy link
Contributor

jgarzik commented Jul 14, 2014

Looks mostly OK, modulo nits.

Do we want to be able to find pruned nodes? Seems like allocating a NODE_xxx service bit in this PR is appropriate.

@gmaxwell
Copy link
Contributor

The bit ought to depend on willingness to at least relay the most recent N transactions from the tip. N=288 by definition sounds good to me, but if it's in the bit definition perhaps it needs more shed painting, which is why I didn't recommend this above (for this pull, e.g. we could do it in a separate one).

@jgarzik
Copy link
Contributor

jgarzik commented Jul 14, 2014

@gmaxwell To forestall shed painting, I observe that NODE_NETWORK behavior has varied over time; only it's general definition "a full node!" has remained static.

As such, it seems reasonable to add NODE_PRUNED or whatever we want to call the high level attribute being advertised. If it's only minor tweaks to find a good value for N, that seems like something that could be performed in-tree before the next release.

It's all about communication. A release note "NODE_PRUNED is experimental until 0.11" can further extend the life.

@laanwj
Copy link
Member

laanwj commented Jul 14, 2014

What about adding a service bit NODE_UTXO? And then having full nodes advertise it as well? This has been proposed before and I think that was a good suggestion (by @maaku?). Pruned nodes would only advertise NODE_UTXO.

This would give NODE_NETWORK - starting from version X - the meaning of 'can serve blocks', and NODE_UTXO the meaning of 'tracks UTXO and can validate transactions'.

This way, service bits actually tell about provided services. I like 'negative' service bits like NODE_PRUNED considerably less.

@sipa
Copy link
Member

sipa commented Jul 14, 2014

I would move the meaning of block-servavility out of NODE_NETWORK, not the
complement. Reason: we don't really know in what ways the remainder of the
functionality will be split off in the future, while the ability to serve
blocks is well defined. Let NODE_NETWORK remain the kitchen sink, and give
new bits a well defined meaning.

As to the meaning itself, I have previously proposed to use 2 service bits,
the combination of which indicates one of 4 levels (e.g. 0,288,4032,all or
288,2016,52500,all if we want some mandatory serving). Discussion mostly
turned into using such a solution vs. adding a field to CAddress to
indicate this information with more granularity.

@gmaxwell
Copy link
Contributor

I was trying to avoid the granularity rathole here. :) Can we please put the new flag in a subsequent pull to avoid delaying this based on that? The approach of removing node network on a pruning node is safe if far from perfect... and will suffice until the extra behavior is hammered out.

@jgarzik
Copy link
Contributor

jgarzik commented Jul 14, 2014

I see that shed painting was not forestalled, @gmaxwell :)

ACK

@rdponticelli
Copy link
Contributor Author

Most nits has been addressed, and I added a branch in my repository for anybody willing to test the rejection instead of disconnecting case:

https://github.com/Criptomonedas/bitcoin/tree/prunedreject

It seems to work pretty fine, just a little more resource wasteful than disconnecting.

@sipa
Copy link
Member

sipa commented Jul 15, 2014

utACK

@maaku
Copy link
Contributor

maaku commented Jul 15, 2014

ut?

@jgarzik
Copy link
Contributor

jgarzik commented Jul 15, 2014

+1

@maaku
Copy link
Contributor

maaku commented Jul 15, 2014

You would want to serve not just the most recent blocks, but also a
range of past blocks. Otherwise it would be very difficult to perform an
initial block download in a scenario where most nodes are pruning.
Adding a field to CAddress seems the more compatible approach with this
requirement.

On 07/14/2014 08:03 AM, Pieter Wuille wrote:

I would move the meaning of block-servavility out of NODE_NETWORK, not the
complement. Reason: we don't really know in what ways the remainder of the
functionality will be split off in the future, while the ability to serve
blocks is well defined. Let NODE_NETWORK remain the kitchen sink, and give
new bits a well defined meaning.

As to the meaning itself, I have previously proposed to use 2 service
bits,
the combination of which indicates one of 4 levels (e.g. 0,288,4032,all or
288,2016,52500,all if we want some mandatory serving). Discussion mostly
turned into using such a solution vs. adding a field to CAddress to
indicate this information with more granularity.


Reply to this email directly or view it on GitHub
#4481 (comment).

@gmaxwell
Copy link
Contributor

@maaku absolutely, but I think we should do that as part of a pull that turns back on network services bits. This pull just turns the node into a client, and the only reason to keep any blocks at all is otherwise a reorg leaves the node stuck and it needs a total (30gbyte) reinit, and while it's stuck it's forked and potentially following a losing chain.

#ifdef ENABLE_WALLET
if (fAllowPruned) {
if (SoftSetBoolArg("-disablewallet", true))
LogPrintf("AppInit2 : parameter interaction: -allowpruned=1 -> setting -disablewallet=1\n");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those checks and the message don't belong here but in Step 2: parameter interactions in init.

@@ -97,6 +97,7 @@ string strMiscWarning;
bool fLogTimestamps = false;
bool fLogIPs = false;
volatile bool fReopenDebugLog = false;
bool fPruned = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This really doesn't belong in util.

I'd say main, but apparently you need it inside net, which feels wrong. Feel like moving the pnodeLocalHost code to init?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about passing an extra parameter to StartNode to allow setting the service bits from the caller in init? Would that be a correct solution? It would seem to be simpler and less invasive, wouldn't it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree it does not belong in util, but also a parameter to StartNode does not seem appropriate. See NODE_EXT_SERVICES in the following WIP branch at https://github.com/jgarzik/bitcoin/tree/2014_ext_services

@sipa
Copy link
Member

sipa commented Aug 3, 2014

@jgarzik Please, let's not make this dependent on how to expose this functionality to the network yet, that can come later. All we need for now is something that disables full node functionality when running pruned.

EDIT: Oh, you mean just modifying nLocalServices from init? That seems fine too.

@jgarzik
Copy link
Contributor

jgarzik commented Aug 3, 2014

@sipa Correct, that's all I meant. Local service configuration will ultimately be multi-step, and can be handled directly from init.

@rdponticelli rdponticelli mentioned this pull request Aug 14, 2014
@BitcoinPullTester
Copy link

Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/p4481_d00a934cc05301d6a08f8d686428c4fd704ed76b/ for binaries and test log.
This test script verifies pulls every time they are updated. It, however, dies sometimes and fails to test properly. If you are waiting on a test, please check timestamps to verify that the test.log is moving at http://jenkins.bluematt.me/pull-tester/current/
Contact BlueMatt on freenode if something looks broken.

@rdponticelli rdponticelli changed the title Allow the node to run with history pruned. Add a switch to allow running in a pruned state Aug 26, 2014
@BitcoinPullTester
Copy link

Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/p4481_eae33b1af4f866257a84bcb438a1768fff07a63e/ for binaries and test log.
This test script verifies pulls every time they are updated. It, however, dies sometimes and fails to test properly. If you are waiting on a test, please check timestamps to verify that the test.log is moving at http://jenkins.bluematt.me/pull-tester/current/
Contact BlueMatt on freenode if something looks broken.

@sipa
Copy link
Member

sipa commented Aug 27, 2014

Untested ACK.

@sipa
Copy link
Member

sipa commented Aug 27, 2014

There are a few changes I'd like to make, but let's do that post-merge:

  • Merge the block/undo data file handling; for now, it seems they will be deleted simultaneously anyway.
  • Make the pruning depth configurable.
  • Abstract the deletion code out of the startup routine, and into something that can run regularly.

EDIT: this is actually about #4701.

@rdponticelli
Copy link
Contributor Author

Added incompatibility with -txindex, as requested.

@BitcoinPullTester
Copy link

Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/p4481_9045aa715c2a043af244d14170fc11b84f986dcb/ for binaries and test log.
This test script verifies pulls every time they are updated. It, however, dies sometimes and fails to test properly. If you are waiting on a test, please check timestamps to verify that the test.log is moving at http://jenkins.bluematt.me/pull-tester/current/
Contact BlueMatt on freenode if something looks broken.

The check is now simpler, somewhat more efficient, and
covers more data, to be sure the node can reorganize.
These are the main functional changes on this state:

* Do not allow running with a wallet or a txindex.
* Check for data at startup is mandatory up to last 288 blocks.
* NODE_NETWORK flag is unset.
* Requests for pruned blocks from other peers is answered with "notfound" and they are disconnected, not to stall their IBD.
* The range of blocks pruned is logged.
@BitcoinPullTester
Copy link

Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/p4481_efbf886cbe560950f432b5af78f63d4a57c81b51/ for binaries and test log.
This test script verifies pulls every time they are updated. It, however, dies sometimes and fails to test properly. If you are waiting on a test, please check timestamps to verify that the test.log is moving at http://jenkins.bluematt.me/pull-tester/current/
Contact BlueMatt on freenode if something looks broken.

@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants