Skip to content

Conversation

@laanwj
Copy link
Member

@laanwj laanwj commented Mar 28, 2016

This is by no means ready, but anyhow this builds on #7756 and

  • Adds a streaming API to the HTTP server. This allows streaming data to the client chunk by chunk, which is useful when not the entire data is available at once or it is huge and wouldn't fit (efficiently) in memory.
  • Allows downloading the entire UTXO set through /rest/utxoset. This is a raw dump of all outputs, the state normally hashed by gettxoutsetinfo. The dump is performed in the background by making use of leveldb snapshotting, so without keeping cs_main locked.
    • This can be useful for analysis purposes if you don't want to mess with bitcoin core's database
    • Filename (via content-disposition) is utxoset-<height>-<bestblockhash>.dat. Also a custom X-Best-Block and X-Block-Height header is added.

It matches:

$ src/bitcoin-cli -datadir=/store/tmp/testbtc gettxoutsetinfo
{
...
  "hash_serialized": "5017f82bbb82a8199ae0fbaa9e5881a0c82575db89e6edd5b39414b35299363b",
...
}
$ wget --content-disposition http://127.0.0.1:8332/rest/utxoset 
2016-03-28 22:58:32 (44.3 MB/s) - ‘utxoset-404681-0000000000000000034854f5a3ab27cfbc220a42c75061dd13d2067cda71191d.dat’ saved [1291578967]
$ ~/bin/dsha256 utxoset-404681-0000000000000000034854f5a3ab27cfbc220a42c75061dd13d2067cda71191d.dat
5017f82bbb82a8199ae0fbaa9e5881a0c82575db89e6edd5b39414b35299363b utxoset

TODO

Note that the HTTP streaming API could in principle also be used for other large data (say, wallet backups), or even for websocket-like event notification.

@paveljanik
Copy link
Contributor

Looks like evhttp_send_reply_chunk_with_cb is new in libevent 2.1 which is in alpha as of now.

@laanwj
Copy link
Member Author

laanwj commented Mar 29, 2016

Looks like evhttp_send_reply_chunk_with_cb is new in libevent 2.1 which is in alpha as of now.

Weird. What good is a chunk function if you have no clue if the data was sent. I'll take a look.

@laanwj laanwj removed the REST label Mar 29, 2016
@laanwj laanwj force-pushed the 2016_03_utxo_streaming branch from b307590 to 073948d Compare April 28, 2016 11:55
@sipa
Copy link
Member

sipa commented Jun 2, 2016

It seems the last stable release of libevent (2.0.22) was 2.5 years, though the master branch is being updated still. Do we want for libevent 2.1 for this, or find another way?

@laanwj laanwj added this to the Future milestone Jun 9, 2016
@laanwj
Copy link
Member Author

laanwj commented Jun 9, 2016

It seems the last stable release of libevent (2.0.22) was 2.5 years, though the master branch is being updated still. Do we want for libevent 2.1 for this, or find another way?

Yes, libevent version management is like that, unfortunately.

I'd tend to include a newer libevent in depends, then disable the functionality when building with older libevent.

This will be too late for 0.13. Let's hope there will be a stable libevent release again before 0.14 which includes this. Not holding my breath though.

This builds on bitcoin#7756 and

- Adds a streaming API to the HTTP server. This allows streaming data to
  the client chunk by chunk, which is useful when not the entire data is
  available at once or it is huge and wouldn't fit (efficiently) in
  memory.

- Allows downloading the entire UTXO set through `/rest/utxoset`. This
  is a raw dump of all outputs, the state normally hashed by
  `gettxoutsetinfo`. The dump is performed in the background by making
  use of leveldb snapshotting, so without keeping cs_main locked.

    - This can be useful for analysis purposes if you don't want to mess
      with bitcoin core's database

    - Filename (via content-disposition) is
      `utxoset-<height>-<bestblockhash>.dat`. Also a custom
      `X-Best-Block` and `X-Block-Height` header is added.
@laanwj laanwj force-pushed the 2016_03_utxo_streaming branch from 073948d to 2498324 Compare September 28, 2016 15:24
@laanwj
Copy link
Member Author

laanwj commented Sep 28, 2016

Rebased, updated for boost-removal from httpserver.h

// LogPrintf("set_http_chunk_cb\n");
{
std::unique_lock<std::mutex> lock(cs);
evhttp_send_reply_chunk_with_cb(req, databuf, &http_chunk_cb, this);
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess this requires libevent2.1 (depends package is still on 2.0.x IIRC)

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry.. that was already discussed.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I need to find exactly what version this was introduce in and guard the streaming stuff with #if LIBEVENT_VERSION_NUMBER >= 0x0201XXXX. I think it can only be supported for newer libevent .

Copy link
Member Author

@laanwj laanwj Sep 28, 2016

Choose a reason for hiding this comment

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

For reference, the commit that introduced evhttp_send_reply_chunk_with_cb libevent/libevent@8d8decf , first appearing in version 0x02010401 is from 2009, and that's still the beta branch. I'm getting a bit concerned about libevent's release process.

Copy link
Contributor

Choose a reason for hiding this comment

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

RE libevent release process -- several projects are feeling the limits of libevent http support, and moving to https://github.com/ellzey/libevhtp

I had to do that in one project, in order to support streaming chunked http downloads.

libevent's http was really written for simple app servers with small replies.

Copy link
Member Author

@laanwj laanwj Sep 29, 2016

Choose a reason for hiding this comment

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

I know of that project, but I'd prefer to avoid adding another dependency. It can be considered if there is really no other way out, but it seems to me that chunked downloads can be done with that function.

This needs a better interface so that HTTPServer's users (such as rest)
can query capabilities.
@laanwj laanwj force-pushed the 2016_03_utxo_streaming branch from 1bc34c2 to 5cd59bb Compare September 29, 2016 07:40
@fanquake fanquake mentioned this pull request Oct 3, 2016
@laanwj
Copy link
Member Author

laanwj commented Oct 18, 2016

Closing this. I think it was a nice experiement but I don't expect to get around to it again in the near future.
If anyone needs this functionality feel free to pick it up.

@laanwj laanwj closed this Oct 18, 2016
@sipa
Copy link
Member

sipa commented Oct 18, 2016 via email

@laanwj
Copy link
Member Author

laanwj commented Dec 6, 2017

For anyone thinking about picking this up:

The good news here is that libevent 2.1 is out of alpha, and is stable as of 2.1.7 at this moment.

The bad news is that it might be impossible to stream reliably using libevent's http server. At least it's mentioned as one of the motivations for the libevhtp replacement:

As far as I know, streaming data back to a client is hard, if not impossible without messing with underlying bufferevents.

So I'm not sure "The timeout actually runs while downloading, causing it to break off after downloading." mentioned in the OP is solvable. It might be with some hack.

@NathanFrench
Copy link

I will be happy to assist with any migration issues to libevhtp if this project decides to go this route.

Cheers!

@laanwj laanwj mentioned this pull request Aug 27, 2020
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
@maflcko maflcko removed this from the Future milestone Jul 23, 2025
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.

8 participants