Bitcoin full node and query server

September 2018

Archive of the libbitcoin Slack #general channel.

Saturday, September 1, 2018

M
mariano01:24
Ups ! ...
☁️ 2
N
narodnik08:13
@evoskuil or anybody else... do you know any good grammar parser systems in C++? I'm currently using flex + bison

Monday, September 3, 2018

vdeurzen07:37
@narodnik you could look at Boost Spirit
👍 1

Tuesday, September 4, 2018

vdeurzen11:11
I'm wondering, would it be possible to replace the logging solution in libbitcoin? What I mean by that is, could I supply my own logger that is then used also by the library? My app has different logging requirements and I would be interested in structured (json) logging
🤔
neillm12:02
@vdeurzen Of course it's possible, you have the code 😉
vdeurzen12:28
hehe 😛
true
(edited)
The complexity is though, that I believe some log lines will include some formatting directives, which means I can't just change the logger, I'd have to change where it's used too 😐
neillm12:33
If you want structured json, I don't see how else you could get it without changing where it's used
Unless the structure was "logline" : "..." 😉
evoskuil14:20
The log system has configured sinks. However it is intentional that log line format is unstructured.
vdeurzen15:01
Hmm, I could possibly change the sinks indeed, that might be exactly the right approach @evoskuil and @neillm that would be a good structure to start with 🙂
evoskuil15:03
@pmienk implemented the current log system.
vdeurzen15:04
@pmienk did you consider using fmt rather than boost::format?

Wednesday, September 5, 2018

Daniel Krawisz04:59
Hello, thanks for inviting me.
Basically I have to build an enormous bitcoin wallet project in an absurdly short amount of time.
evoskuil06:29
Hi @Daniel Krawisz how can we help?
Daniel Krawisz06:36
Oh I just want to be able to talk to you if I need anything.
Also I would want to talk about whether you would want to include some work that I might do supporting spv mode and bch and if so how you would want me to do them.
But it's a while before I would even begin something like that so no rush.
Oh and also if there's work that already exists in those directions that you know of.
evoskuil06:40
Cool, yes we are already working on incorporating BCH, LTC and FTC into node and server config. @Fil is leading that work. There should be no changes required in the wallet APIs.
Daniel Krawisz06:41
Oh well I'm really glad to hear that then
I'll talk to him if I have some time to spare to help with that.
evoskuil06:41
We do have a design principle in place for SPV, but it’s very loose.
Great, thanks!
Daniel Krawisz06:41
Do you have the spv design principle written down anywhere?
evoskuil06:44
No, but @Mlmikael can probably lay out the principles for you. He suggested it a while back.
Daniel Krawisz06:44
Ok thanks
I think I'm all set now!
evoskuil06:46
This pertains to a light node design, not the wallet store. For current work on a wallet store/API you might contact @narodnik .
Daniel Krawisz06:46
Sure, I don't know anything about that.
I don't know if we have any need for that right now.
evoskuil06:47
We are also working to integrate Electrum and Libbitcoin Server via the ZeroMQ interface.
I think @haarts is on that, also @lclc.
Daniel Krawisz06:48
Oh cool well I know Justus Ranvier loves zeromq
I don't think I'm going to be working with something like that at all though.
evoskuil06:50
@neillm is working on the websockets (and JSON RPC compat) server interface, which sits on the ZeroMQ interface.
Daniel Krawisz06:59
Thanks!
I think I'm all set for now.
👍 1
lclc07:18
@Daniel Krawisz are you working for Stash Crypto / Chris Odom ?
Daniel Krawisz07:21
Yes
lclc07:22
Still with Open Transactions ?
Regarding libbitcoin and BCH: We are only working on a LTC and FTC for now. If anyone has the ressources for BCH we are happy to help with that but our sponsors aren’t keen on it otherwise..
evoskuil07:24
Bitprim has written it on a fork.
With your parameterization work it shouldn’t be hard to incorporate the rest (forks).
Daniel Krawisz07:25
Oh ok cool
I didn't realize that bitprim was so closely related to libbitcoin.
I've already been looking at that one.
evoskuil07:25
It is libbitcoin, with some forward features.
Daniel Krawisz07:26
Oh ok great.
I think everybody should just use libbitcoin so I'm glad to understand that it's actually the same thing.
evoskuil07:28
They are front-running some features that will take us longer to incorporate because of our additional requirements. But happy to have them doing it.
Daniel Krawisz07:33
Cool well I'm working on some strange ideas but I think that I'll be able to put the wallet together that I have to make and it'll work.
@evoskuil I've been re-thinking your proposed solution for safety regarding the derivable values in bc::settings. I came to the conclusion that if we use standard C++ encapsulation mechanisms we can get it all: safety and performance. So we have non-derivable values upon which other (derivable) values depend. I would make both of them private members and only make them accessible through getter methods. For the non-derivable values we'd then implement setter methods that will also update the dependent values. Consequently, the derivation of the values would be an one-off computation rather than recurring for each use. This implementation would still be compatible with boost::program_options because the bc::settings setter methods can be passed into the boost::program_options's notifer method which then causes the value to be set according to the configuration. The only drawback would be that bc::settings would not be perfectly consistent with the other settings classes. But with the current solution it's not either.
👍 1
@evoskuil when will you get around to do some review? Would be nice to get this one off my plate https://github.com/libbitcoin/libbitcoin/pull/1022
evoskuil09:13
Sorry, been on the road.
No worries. And thanks for the quick review 👍

Saturday, September 8, 2018

evoskuil07:17
Back home for the next 12 days, then Honeybadger, then Scaling.
👍 1

Sunday, September 9, 2018

N
narodnik17:43
@evoskuil top of the file in src/math/hash.cpp:
#include "../math/external/crypto_scrypt.h"
#include "../math/external/hmac_sha256.h"
#include "../math/external/hmac_sha512.h"
#include "../math/external/pkcs5_pbkdf2.h"
#include "../math/external/ripemd160.h"
#include "../math/external/sha1.h"
#include "../math/external/sha256.h"
#include "../math/external/sha512.h"
Is this a mistake? Why not simply "external/..."?
evoskuil17:46
No, why does it seem like a mistake?
neillm18:54
@narodnik It looks like a relative path to what's included in the CPPFLAGS: src_libbitcoin_la_CPPFLAGS = -I${srcdir}/include from the src dir, where ${srcdir} is ".". So backing up one from src/include gives src for src/math/external/*.h
N
narodnik18:56
@evoskuil well surely #include "external/..." is sufficient?
evoskuil18:56
root is sufficient 🙂
N
narodnik18:56
(hash.cpp and external/ share the same directory)
evoskuil18:57
It's a hierarchy.
N
narodnik18:57
ok
evoskuil18:57
These are the external files used by math classes/fns
N
narodnik18:57
@neillm generally for -I includes we use < ... > but it's a style choice
ok it's not a big deal
neillm18:58
These headers are not supposed to be exposed though, so I thought that was the distinction. Not sure
evoskuil18:58
"" is used for local includes, as opposed to published.
That's also why these headers are in the src dir.
<> is relative to base include directories, whereas "" is only relative to the including source file, so the difference is meaningful.

Wednesday, September 12, 2018

vdeurzen13:28
Where should I look for a method that gets me the latest block of the longest chain? I see that block_chain has is_stale() but I would like to perform an action already when I'm N blocks from the top ...
Most things I've seen in the code seem to query the local database, but I want to check with the network / existing chain rather than the database (at least while starting up)
hmm, is_stale can be configured with the notify_limit_seconds, so that at least gets me there approximately ... would love to be more precise though 🤔
evoskuil17:39
This is not possible, in any implementation.
evoskuil19:32
The network doesn't have a chain. A chain exists only in the databases of individual nodes. There is no way to know if a block obtained from any node is on any chain at all unless you validate its full history. There is also no way to know that a block on a validated chain is on the longest chain unless you validate each candidate chain. And given that you may not see every chain, you can't actually know even if you validate every chain you see. The best you can do is validate each chain you see and from that obtain the strongest block. In libbitcoin this is the top block of the confirmed chain.

Thursday, September 13, 2018

vdeurzen09:33
ok, makes sense, thank you @evoskuil
I just use the is_stale() which is actually just fine for my use-case
I'm now synching the testnet, looking good so far. Wondering a little bit about the memory usage though 0.o, have any profiles been done?
evoskuil09:37
Are you working in v3?
vdeurzen09:45
bitprim at the moment, should indeed check the v3 libbitcoin (I'm currently 18.7% memory usage (24GB total), 600K blocks received on testnet)
I'll double check with libbitcoin v3 too
and that reminds me I also have to still create the report / issue regarding the latest satoshi client and regtest network (if you are still interested)
Slackbot09:46
👻
evoskuil09:53
master is staging for next release, and is still early. V3 memory usage is very flat, increasing slightly with overall chain/store size. The store is memory-mapped files, and the operating system is fee to use any available memory for caching pages.
Process memory usage should be on the order of 100mb or so after syncing most of testnet.
vdeurzen09:57
I was expecting something like that indeed, it seems to have started levelling off a bit indeed
evoskuil09:58
From my limited testing it’s about half the memory usage of bitcoind during initial block download. And since we don’t have a memory pool it should do even better after.
(edited)
vdeurzen10:02
it's pretty quick so far
evoskuil10:03
v3 initial block download is actually very slow. that's a major piece of work in v4.
vdeurzen12:20
looking forward to seeing that work 🙂
will that also include the work on different chains?
I am considering writing up some conan-files for libbitcoin to allow using it with the conan package manager (which makes it rather easy to start using libraries like this) 🙂
Somebody merge that please
👍 1

Friday, September 14, 2018

M
Mlmikael01:43
@Daniel Krawisz, we'll need to wait for V4 to get stable, it will have header sync.
M
Mlmikael02:53
How does the Bitcoin address index work in LibBitcoin? I see the "fetch-history" aka "fetch_history3" call from Bitcoin Explorer and Client to the Server, which leads to this logic in libbitcoin-server's src/interface/blockchain.cpp: node.chain().fetch_history(address_hash, limit, from_height, std::bind(&blockchain::history_fetched, _1, _2, request, handler));
and that one in turn leads to https://github.com/libbitcoin/libbitcoin-blockchain/blob/master/src/interface/block_chain.cpp#L1538 which leads to taking the address_database instance held by the block_chain instance. looking in address_database however i don't see that it's accessing a persistent structure?
(edited)
M
Mlmikael03:06
It looks to me that there's a configuration setting [server.]index_addresses which enables/disables the address index, and, it's enabled by default. I don't find this setting included in the documentation at https://github.com/libbitcoin/libbitcoin-server/wiki/Database-Settings , shouldn't it be there?
(edited)
M
Mlmikael03:20
(@evoskuil that setting is about modulating the address index' behavior, not enabling/disabling it)
evoskuil03:20
same thing
M
Mlmikael03:21
how could you use that setting to disable the address index, by setting it to #7fffffff...?
yeah so the address_database is the real deal, great. 🙂 and it's implemented in terms of libbitcoin-database's persistent hashtable facilities 👍
M
Mlmikael03:34
@evoskuil question, what exactly does address_database index over? The code in the block_chain::fetch_history that invokes the address_database and then translates address_database's response into the data format that the history_fetch_handler receives, I don't understand it so it's here https://github.com/libbitcoin/libbitcoin-blockchain/blob/master/src/interface/block_chain.cpp#L1538 :
GitHub
Bitcoin Blockchain Library. Contribute to libbitcoin/libbitcoin-blockchain development by creating an account on GitHub.
Untitled C++ · 1004 B
void block_chain::fetch_history(const short_hash& address_hash, size_t limit,
    size_t from_height, history_fetch_handler handler) const
{
    if (stopped())
    {
        handler(error::service_stopped, {});
        return;
    }

    // Cannot know size without reading all, so dynamically allocate.
    chain::payment_record::list payments;
    size_t count = 0;

    // Result set is ordered most recent tx first (reverse point order in tx).
    for (auto payment: database_.addresses().get(address_hash))
    {
        if (count++ == limit)
            break;

        const auto tx = database_.transactions().get(payment.link());
        const auto height = tx.height();

        if (height < from_height)
            break;

        // Copy of each payment record above so can be modified here.
        payment.set_height(height);
        payment.set_hash(tx.hash());
        payments.push_back(payment);
    }

    handler(error::success, std::move(payments));
}
database_.addresses().get(address_hash) gives you an "address_result" instance which is an iterator. for ( .... ) counts the iterator for you and feeds each iterated-over value into "auto payment". @evoskuil can you please confirm payment's type?
the "payments" value passed to the history_fetch_handler, is a vector of chain::payment_record - payment-record is an Unspent Transaction Output structure so.. the address index indexes spent and unspent UTXO:s??
Wait, this is an incorrect comment isn't it, https://github.com/libbitcoin/libbitcoin/blob/master/include/bitcoin/bitcoin/chain/payment_record.hpp#L92 ? it says /// The blockchain height of the point. uint64_t link() const; but link is actually an offset into some file isn't it? @evoskuil @neillm
(edited)
evoskuil04:29
yup
M
Mlmikael05:13
@evoskuil, does address_database resolve **UTXO:s** (rather than Bitcoin transactions), and specifically, both "unspent" and spent UTXO:s?
evoskuil05:14
it indexes payments to standard addresses.
M
Mlmikael05:14
What does history_fetch_handler actually get?
The two data queries that I like to answer are, "has there ever been any transactions to/from this address?", and, "which are the (unspent) UTXO:s that currently are owned by this address? (as in my privkey can spend these UTXO:s)"
evoskuil05:30
payments to/from a standard address
payments include the tx hash and input/output index (what you are calling a utxo).
M
Mlmikael06:34
@evoskuil, does the address database allow lookups by height interval (in a particularly performant way, for incremental syncing of transaction/utxo history)?
Daniel Krawisz10:04
@MlmikaelHow far away is version 4?
evoskuil10:29
Planned end of year release.
Daniel Krawisz10:30
Oh wow that's awesome.
evoskuil10:32
The major work is the continuous parallel block download, which is largely complete and merged, though still working out issues. The websockets work is also largely complete, as is the tx metadata pool (which is merged but not integrated yet).
(edited)
Daniel Krawisz10:33
Yeah I remember you talking about that at a conference.
Well if you know something I could be doing now to bring spv-mode closer let me know & I'll look around for something too, but end of the year should be good.
It doesn't look like you've got bloom filters, or the p2p messages like FilterLoad, or the partial merkle tree data structure that gets sent. I could probably get those parts ready pretty soon if nobody else is doing them.
vdeurzen10:59
Any video of those talks ?
evoskuil11:00
Yeah, youtube, Satoshi’s Vision conf has a good talk.
Slackbot11:00
👻
vdeurzen11:01
cool, thx!
evoskuil11:01
We implement all of the network types, but purposely avoid implementing protocols for bloom filters.
(edited)
Daniel Krawisz11:02
Why not?
evoskuil11:03
Privacy, DOS, client-server protocol in the P2P network...
Daniel Krawisz11:03
ok
evoskuil11:04
It's so problematic it became the primary justification for introducing identity into the p2p protocol.
👍 1😬 1
1 reply · Revive · last Sep 14, 2018
Revive18:09
This needs to be highlighted, so true
Daniel Krawisz11:08
Where are the network types implemented?
I'm having trouble understanding how p2p works
evoskuil11:40
yeah, proactor can be hard to follow.
the types are in the base libbitcoin library under /message
Daniel Krawisz11:43
Oh there we go. Thanks!
Well I don't think there's anything I can really do for you right now but thanks I'll be in touch
evoskuil11:44
👍
vdeurzen12:26
@evoskuil if the database get's corrupted, is there anyway to fix it without having to resync the entire chain?
evoskuil12:35
No, there is no database repair. If it’s corrupt there is no way to know how it is corrupt.
vdeurzen12:36
pity, thx though 🙂
evoskuil12:36
This is the case with Core as well, they just don’t deal with it.
vdeurzen12:36
wouldn't that be a nice feature to have though?
evoskuil12:37
No, the store is a cache of public data. It would be a design flaw to implement any feature that traded performance for general recoverability.
Better to improve sync, which is recovery.
vdeurzen12:39
Sure, but having recoverability doesn't have to decrease performance imho
evoskuil12:39
Yes it does.
vdeurzen12:39
why?
evoskuil12:41
First, you cannot detect arbitrary corruption. The hardware can fail, and you use hardware to detect failure...
You can (mostly) prevent corruption due to hard stop (process termination) using journaling, but that has a cost.
(edited)
👍 1
vdeurzen12:43
imho, I think that cost might actually be low enough compared to the time needed for a sync, but I haven't looked into it enough to say more about it
evoskuil13:34
There's no clear ideal ratio for cost tradeoff. How much performance (profit) should a miner sacrifice so that they don't have to restore the chain if a server is hard stopped? How much time is actually required to restore the chain from the network?
On the other hand libbitcoin does provide a write flushing option which limits abort corruption (still fully detectable) to write operations. This has a material performance impact but has a low probability of producing corruption.
vdeurzen14:45
that would help indeed
I'm trying to ensure the service I'm building is highly available and won't be 'booting' for 2h if the database is corrupt.
I'll be backing up the data too, but with it being actively written too that might be less-than-ideal
evoskuil18:47
That’s easy, just don’t kill the process. You cannot back up the libbitcoin store while it is open for write. Also, some more info here: https://github.com/libbitcoin/libbitcoin-server/wiki/Frequently-Asked-Questions
(edited)
Revive21:25
That is a very informative faq
👍 1

Saturday, September 15, 2018

Revive00:10
Will the adoptions of bip150 and 151 on bitcoin core (as a soft fork I imagine) affect non conforming nodes directly or only in a discriminatory manner?
evoskuil00:12
Those are not forks, they are additions to the P2P protocol.
(edited)
Revive00:12
Oh
evoskuil00:13
If widely adopted they will lead to privatization of the P2P network.
Revive00:13
But not as an immediate effect. That's all I meant by soft fork I suppose
Its by adoption rate
evoskuil00:14
That's not a soft fork.
BIP151 is pointless without BIP150, and BIP150 establishes private connections between identifiable parties.
It's one of those great features that one must hope doesn't get widely used.
Revive00:16
👍
M
Mlmikael10:09
@evoskuil @vdeurzen it should be possible to implement a self-consistency check on the data in LibBitcoin's blockchain files, without doing writing. the major expense involved in a LibBitcoin deployment is SSD wear, right, you want the SSD to work for several years even if there were. the self-consistency check could self-heal either by repairing, or by truncating/cutting files at the block height where inconsistencies were found

Sunday, September 16, 2018

evoskuil04:23
You would be reproducing code integrated into the devices themselves.
evoskuil05:33
Even if it was possible to detect a failing drive with a "consistency check" it is not possible to stop in the midst of what needs to be an atomic commit (across multiple files) and expect the resulting store to be consistent. But again, this should not be possible since the drive should itself detect and disable failing sectors. All you should notice is your drive getting smaller.
N
narodnik09:40
usually the correct way is there to exist a lockfile when the file is opened but not closed properly. This would be implemented in addition to the boost lockfile currently used that prevents concurrent write access to the database.
evoskuil09:50
This is already implemented.
Since v3 there is a flush_lock while there is an unflushed write. Upon startup if the file is there the store is corrupt (due to a process termination with an unflushed write). @Mlmikael Is looking to detect/correct read/write failures at the disk level. I consider this out of scope as it is the job of the hardware and its firmware.

Monday, September 17, 2018

skaht23:19
The novel application of BLS aggregate threshold signatures could be a major game changer to the internationalization of existing centralized equity issuance processes.

Tuesday, September 18, 2018

FYI, I'm on vacation till the end of this month. Please contact @lclc if you need something from the FDF during this time. See you at scaling @evoskuil!
👍 1

Wednesday, September 19, 2018

M
Mlmikael07:21
@evoskuil what's WebSockets used for in LibBitcoin?
1 reply · neillm · last Sep 19, 2018
neillm11:44
Nothing yet. When added, the goal is to support all client-server operations that exist today via zmq. This more easily opens up access from native websocket (web/nodejs) applications, rather than trying to find a javascript zmq stack and using the "lower-level" zmq messaging format.
(edited)
M
Mlmikael07:23
This is the case with Core as well, they just don’t deal with it.
@evoskuil Bitcoin Core does have some logic to rewind the last N blocks after an unexpected shutdown. i also did not see any logic to recalculate the whole Bitcoin blockchain as a self-validation measure in Bitcoin Core.
(edited)
M
Mlmikael07:28
<higher prio topic coming below :)) >
You would be reproducing code integrated into the devices themselves.
@evoskuil no you're missing my point - it is the responsibility of a storage device (e.g. SSD) to keep its data store in integrity. Indeed it may not keep integrity. A filesystem (e.g. ZFS) may add a checksumming layer to storage device access, so that reads will fail if its underlying disk data was corrupted. In case of unexpected shutdowns in particular, self-validation to identify anything broken and rewind all affected, would make all sense - rather than for instance terminate and require administrator intervention which is LibBitcoin's current behavior. I agree that it not is reasonable for software behavior to be coherent if persistent storage breaks, just like it not is reasonable for software behavior to be coherent if RAM or CPU break. However, unexpected shutdowns happen, and also a user may like to run self-checking logics - in particular given the fiat cost of SSD wear for rewriting the whole blockchain, and the time it takes to resync the blockchain from scratch, some self-validation would make sense. I don't follow LibBitcoin's database models very well yet so I don't understand yet what degree of complexity they are. </higher prio topic coming below :)) >
evoskuil07:35
> > This is the case with Core as well, they just don’t deal with it.
Bitcoin Core does have some logic to rewind the last N blocks...
that’s not dealing with it, that’s denial.
(edited)
evoskuil07:41
The bitcoin blockchain is a cache, not an authoritative record. as such it’s requirements are different than general purpose databases. If there is a hard shutdown libbitcoin always knows whether the store is corrupt. Scanning the store is a complete waste of time. Validating a corrupt store does not make sense. It has nothing to do with the database structures.
M
Mlmikael10:02
@evoskuil @narodnik @neillm (as of v4:) can you please list to me the persistent stores and indexes LibBitcoin maintains now, as in, key(s) and value(s), and logical store order, and data format? Is it documented anywhere? Specifically: * Which are the databases (in the logical sense of database) actually now, what are their names? * How many copies of a transaction and of a block header does LibBitcoin store today, in what files&db:s? * Gossiped tx:es with sufficient txfee are pushed directly into the txdb? * Are transactions spread randomly accross a logical txid->tx raw content persistent hashtable, or is it stored as part of the blockchain blocks storage (tree structure)? * What is the actual block storage model, and what is the disk ordering, including for main chain vs orphan blocks?
evoskuil10:07
@Mlmikael no, not documented.
If you want to understand the intimate details of the database I suggest just referencing the code.
(edited)
M
Mlmikael11:41
@evoskuil i am looking at the code but also some things lack. would you mind writing a couple of lines here, briefly respond to each above? also - what are the conditions for storage of orphaned blocks and their transactions, are they stored indefinitely?
neillm11:51
@Mlmikael The v4 libbitcoin-database has been heavily re-organized and is incomplete (subject to change before release). As mentioned, the code is the best place if you'd like to track it (generally true anyway).
M
Mlmikael12:06
@neillm yes reviewing the v4 code, also yes understand some things will change. i understand there's no point in writing documents when the code is in flux. do you have a minute to describe the approx databases and their formats now?
i'd like to understand if the block_chain instance will let me access orphaned blocks, and what the indexes are optimized for
7 replies · evoskuil, Mlmikael · last Sep 20, 2018
evoskuil18:56
The “primitives” templates implement the entire database. Nothing is read or written if not through them. These implement just a small number of data structures. These rest on an abstract memory model, implemented in the “memory” types. In test cases we implement memory as a data chunk, in production we implement it using operating system file mapping. The “database” classes organize the templates and memory model into specific files each representing a complex data structure.
evoskuil19:02
The ADTs are: array, hash table, and linked list. These maintain data elements as record (fixed size) or slab (variable size). There are three arrays of records (candidate and confirmed indexes of heights and the tx index of tx offsets for a block), one record hash table (headers) one slab hash table (txs) and one record hash table of linked lists (addresses).
evoskuil19:03
Hash tables also use the linked list for maintaining the set of hash conflicts.
M
Mlmikael08:37
@evoskuil the "primitives templates" and "memory types" are classes, or are logical memory regions with their produce/retrieve logics implemented as classes (or both! ?), and the block_chain file is made up of a sequence of those primitive/memory structures only? (By "in test cases we implement memory as a data chunk" you mean your logics are operating on the memory addresses malloc:ed for the data chunk object, instead of on mmap():ed memory addresses.)
M
Mlmikael10:13
Cool! ADT here means Abstract Data Type yes? So block_chain is.. mostly append only? Just to expand what you said above: block_chain contains these six structures?: * the index of height of candidate blocks (type: array of record) * the index of height of confirmed blocks (type: array of record) * the tx index of tx offsets for a block * block headers hash table, i guess key = block hash and value = block header data * transactions slab hash table, i guess key = tx hash and value = raw tx data * address index: hash table of key = bitcoin address hash, value = linked list
evoskuil14:24
They are directories in the source code.
evoskuil14:25
The blockchain is append only.
neillm12:06
No, I haven't reviewed the latest changes
M
Mlmikael12:09
@neillm formats are changing because the header-first sync requires it?
1 reply · evoskuil · last Sep 19, 2018
evoskuil17:57
Continuous parallel block download requires it.
neillm12:10
Not sure, I haven't contributed to libbitcoin-database (yet)
M
Mlmikael12:13
ok
@neillm do you know how i can traverse blocks by their children? (as in, orphan chains)
3 replies · evoskuil, Mlmikael · last Sep 20, 2018
evoskuil17:58
Previous block hash is contained in each block’s header.
M
Mlmikael05:21
how do you enumerate a block's children? you have one main chain child, and then >0 stale (or orphan) child blocks right
evoskuil05:28
You don’t
neillm12:14
No, I'd have to look at the code
M
Mlmikael12:38
Does LibBitcoin have any "defragmentation" logic where it's moving around data to put the data relating to the (now-) main chain in a sequence?
1 reply · evoskuil · last Sep 19, 2018
evoskuil18:01
No, libbitcoin never moves or removes a record that it has stored. Blocks form a tree. A “chain” is just an index into that tree.
neillm12:40
Without looking at the code, I can't say. But I don't think so, I think it re-indexes existing data, rather than moving everything around (inefficient and unnecessary)
3 replies · evoskuil, Mlmikael · last Sep 20, 2018
evoskuil18:01
Right, it would be a very significant deoptimization.
M
Mlmikael05:23
this has for instance this consequence right: transactions are stored on disk, in order of arrival, yes? (and not in order represented in blocks, or in order of hash(txid) or the like.)
evoskuil05:29
What is your question?
vdeurzen13:16
libbitcoin::database seems unaware of running in testnet / regtest, which means it will store addresses in mainnet format rather than testnet format.
1 reply · evoskuil · last Sep 19, 2018
evoskuil18:03
The database has no need of consensus rules. Addresses are not stored, address hashes are indexed. The format is unrelated to the coin rules.
M
Mlmikael13:32
I just talked to people about which full node Bitcoin nodes are out there and indeed it's only Bitcoin Core and LibBitcoin (!). BTCD apparently is a line-by-line transcription of an old Bitcoin Core version to GoLang, mostly used to drive Lightning development.
🙂 1
6 replies · evoskuil, Mlmikael · last Sep 21, 2018
evoskuil18:51
It’s my opinion that no fork of a large codebase will survive, especially as a language translation, unless the original codebase dies off.
M
Mlmikael05:54
What effect does this phenomenon have on LibBitcoin? Anyhow Bitcoin is different from traditional software compatibility problems, in that the introduction of implementational incompatibilities is greaetly restrained from the fact that Bitcoin's ability to add new features which could cause such incompatibilities, is very low due to protocol conservacy.
evoskuil05:57
Meh
M
Mlmikael10:16
Ah yes, now I see what you mean 😃 : Yes BTCD forked Bitcoin Core and then translated it to another language. Indeed that is difficult to keep alive yes. LibBitcoin is a separate Bitcoin node implementation and has incentives for it per above, plus Bitcoin Core's obvious limitations, and more.
evoskuil14:23
An independent implementation would not exist if it hadn’t built up the necessary community to keep it alive.
M
Mlmikael02:08
👍
vdeurzen14:13
I seem to also have an interesting versioning issue with transactions within a mined block, the address cache seems to have been parsed with a non-testnet version configured 😕
3 replies · evoskuil, vdeurzen · last Sep 20, 2018
evoskuil18:05
The version value is not part of the node or server, it’s a wallet thing.
vdeurzen06:57
yeah, I found out roughly as much. I should say that I also noticed that the current version of libbitcoin doesn't have the same issue as bitprim. What happens in bitprim is they store all addresses from a block in a database somewhere and they have a cache for those addresses. However, the database doesn't know about testnet/regtest so it uses the default of mainnet. Not sure if a similar issue in libbitcoin might exist, the codebases have diverged a bit too much to say
evoskuil14:26
There is no issue in libbitcoin because the server doesn’t deal with addresses, it deals with address hashes.
vdeurzen14:14
s/parsed/populated/
M
Mlmikael14:34
@evoskuil is there any way to identify / traverse / access stale/orphan blocks?
16 replies · evoskuil, Mlmikael · last Sep 21, 2018
evoskuil18:06
In v4 a weak block can be queried by its hash, and of course its txs and ancestors can be as well.
👍 1
M
Mlmikael10:17
How do I enumerate which weak block children a particular block has 😄
evoskuil14:21
You either read all headers and then monitor for new ones or you don’t do it. There is no scenario in Bitcoin that requires it.
M
Mlmikael02:07
aha you mean, the way to monitor weak block children is simply, listen for blocks as they come in and register their block hashes, and then track which of the previously registered block hashes are not in the main chain anymore - those are the weak blocks. That's the sole way to track them?
evoskuil02:13
Sure, but that’s just the creation of an index. It’s is not at all clear to me what scenario requires this blocktree children (vs blockchain child) index.
M
Mlmikael02:16
wait what do you mean?
evoskuil02:21
What scenario requires this information?
evoskuil02:22
There are an unlimited number of things that could be indexed. The choice to do so implies an important scenario.
M
Mlmikael02:53
blocktree children (vs blockchain child) index.
wait, by "blockchain child" you mean "blocks within the main chain" and by "blocktree children" you mean "blocks within the main chain or stale chains", right?
M
Mlmikael02:57
There are an unlimited number of things that could be indexed. The choice to do so implies an important scenario.
The nature of the blockchain is a tree structure where one branch normally grows longer than all the others, and this is the general form in reality, a tree structure is what it is. The question is not what particular utility accessing the tree structure has, but instead, the tree structure is what it is and data structures should reflect that.
M
Mlmikael03:11
The cost of making a stale block is approx 80,000 USD. If someone spent this money to make a block, I like to inspect it. 🙂 Stale blocks are not a DOS vector.
M
Mlmikael04:05
Ok, thank you for your clarification that in the v4 API, a previously recorded block hash (that was the main chain then) can still be queried even when it's stale now! 👍
evoskuil04:34
Blocks form a tree
evoskuil04:37
Actually no, that’s not the question one asks in such a design exercise. You are describing the normal form of the data, not it’s access patterns based on actual use cases. It is never the case that implementation “should” reflect anything but usage requirements.
👍 1
evoskuil04:38
Then query for it by its hash. But again, what you personally would like is not what drives our design.
evoskuil04:41
Yes, because it is not only useful but is facilitated by the fact that we never delete data (so low cost). This is not the same as navigating children.
M
Mlmikael15:48
Also, what meaning does the word "candidate" have (it's regarding blocks) in https://github.com/libbitcoin/libbitcoin-blockchain/blob/master/src/interface/block_chain.cpp , is it when comparing total work done between two chains?
GitHub
Bitcoin Blockchain Library. Contribute to libbitcoin/libbitcoin-blockchain development by creating an account on GitHub.
1 reply · evoskuil · last Sep 19, 2018
evoskuil18:08
The candidate chain is a pow chain with more proven work than the confirmed chain, and is being downloaded and validated. Once it is validated it is reorged as the confirmed chain.
evoskuil17:57
replied to a thread: view
Continuous parallel block download requires it.
evoskuil17:58
replied to a thread: view
Previous block hash is contained in each block’s header.
evoskuil18:01
replied to a thread: view
No, libbitcoin never moves or removes a record that it has stored. Blocks form a tree. A “chain” is just an index into that tree.
evoskuil18:01
replied to a thread: view
Right, it would be a very significant deoptimization.
evoskuil18:03
replied to a thread: view
The database has no need of consensus rules. Addresses are not stored, address hashes are indexed. The format is unrelated to the coin rules.
evoskuil18:05
replied to a thread: view
The version value is not part of the node or server, it’s a wallet thing.
evoskuil18:06
replied to a thread: view
In v4 a weak block can be queried by its hash, and of course its txs and ancestors can be as well.
👍 1
evoskuil18:08
replied to a thread: view
The candidate chain is a pow chain with more proven work than the confirmed chain, and is being downloaded and validated. Once it is validated it is reorged as the confirmed chain.
evoskuil18:51
replied to a thread: view
It’s my opinion that no fork of a large codebase will survive, especially as a language translation, unless the original codebase dies off.
evoskuil18:56
replied to a thread: view
The “primitives” templates implement the entire database. Nothing is read or written if not through them. These implement just a small number of data structures. These rest on an abstract memory model, implemented in the “memory” types. In test cases we implement memory as a data chunk, in production we implement it using operating system file mapping. The “database” classes organize the templates and memory model into specific files each representing a complex data structure.
evoskuil19:02
replied to a thread: view
The ADTs are: array, hash table, and linked list. These maintain data elements as record (fixed size) or slab (variable size). There are three arrays of records (candidate and confirmed indexes of heights and the tx index of tx offsets for a block), one record hash table (headers) one slab hash table (txs) and one record hash table of linked lists (addresses).
evoskuil19:03
replied to a thread: view
Hash tables also use the linked list for maintaining the set of hash conflicts.

Thursday, September 20, 2018

M
Mlmikael05:21
replied to a thread: view
how do you enumerate a block's children? you have one main chain child, and then >0 stale (or orphan) child blocks right
M
Mlmikael05:23
replied to a thread: view
this has for instance this consequence right: transactions are stored on disk, in order of arrival, yes? (and not in order represented in blocks, or in order of hash(txid) or the like.)
M
Mlmikael05:54
replied to a thread: view
What effect does this phenomenon have on LibBitcoin? Anyhow Bitcoin is different from traditional software compatibility problems, in that the introduction of implementational incompatibilities is greaetly restrained from the fact that Bitcoin's ability to add new features which could cause such incompatibilities, is very low due to protocol conservacy.
evoskuil06:41
meh
M
Mlmikael08:37
replied to a thread: view
@evoskuil the "primitives templates" and "memory types" are classes, or are logical memory regions with their produce/retrieve logics implemented as classes (or both! ?), and the block_chain file is made up of a sequence of those primitive/memory structures only? (By "in test cases we implement memory as a data chunk" you mean your logics are operating on the memory addresses malloc:ed for the data chunk object, instead of on mmap():ed memory addresses.)
M
Mlmikael10:13
replied to a thread: view
Cool! ADT here means Abstract Data Type yes? So block_chain is.. mostly append only? Just to expand what you said above: block_chain contains these six structures?: * the index of height of candidate blocks (type: array of record) * the index of height of confirmed blocks (type: array of record) * the tx index of tx offsets for a block * block headers hash table, i guess key = block hash and value = block header data * transactions slab hash table, i guess key = tx hash and value = raw tx data * address index: hash table of key = bitcoin address hash, value = linked list
M
Mlmikael10:16
replied to a thread: view
Ah yes, now I see what you mean 😃 : Yes BTCD forked Bitcoin Core and then translated it to another language. Indeed that is difficult to keep alive yes. LibBitcoin is a separate Bitcoin node implementation and has incentives for it per above, plus Bitcoin Core's obvious limitations, and more.
M
Mlmikael10:17
replied to a thread: view
How do I enumerate which weak block children a particular block has 😄
M
Mlmikael13:01
What is the name/URL of the blockchain explorer that uses LibBitcoin again?
1 reply · evoskuil · last Sep 20, 2018
evoskuil14:27
Voyager (cancoin)
vdeurzen13:32
is it blockdozer?
evoskuil14:21
replied to a thread: view
You either read all headers and then monitor for new ones or you don’t do it. There is no scenario in Bitcoin that requires it.
evoskuil14:23
replied to a thread: view
An independent implementation would not exist if it hadn’t built up the necessary community to keep it alive.

Friday, September 21, 2018

M
Mlmikael02:07
replied to a thread: view
aha you mean, the way to monitor weak block children is simply, listen for blocks as they come in and register their block hashes, and then track which of the previously registered block hashes are not in the main chain anymore - those are the weak blocks. That's the sole way to track them?
M
Mlmikael02:08
replied to a thread: view
👍
evoskuil02:13
replied to a thread: view
Sure, but that’s just the creation of an index. It’s is not at all clear to me what scenario requires this blocktree children (vs blockchain child) index.
M
Mlmikael02:16
replied to a thread: view
wait what do you mean?
evoskuil02:21
replied to a thread: view
What scenario requires this information?
evoskuil02:22
replied to a thread: view
There are an unlimited number of things that could be indexed. The choice to do so implies an important scenario.
M
Mlmikael02:53
replied to a thread: view
blocktree children (vs blockchain child) index.
wait, by "blockchain child" you mean "blocks within the main chain" and by "blocktree children" you mean "blocks within the main chain or stale chains", right?
M
Mlmikael02:57
replied to a thread: view
There are an unlimited number of things that could be indexed. The choice to do so implies an important scenario.
The nature of the blockchain is a tree structure where one branch normally grows longer than all the others, and this is the general form in reality, a tree structure is what it is. The question is not what particular utility accessing the tree structure has, but instead, the tree structure is what it is and data structures should reflect that.
M
Mlmikael03:11
replied to a thread: view
The cost of making a stale block is approx 80,000 USD. If someone spent this money to make a block, I like to inspect it. 🙂 Stale blocks are not a DOS vector.
M
Mlmikael04:05
replied to a thread: view
Ok, thank you for your clarification that in the v4 API, a previously recorded block hash (that was the main chain then) can still be queried even when it's stale now! 👍
evoskuil04:34
replied to a thread: view
Blocks form a tree
evoskuil04:37
replied to a thread: view
Actually no, that’s not the question one asks in such a design exercise. You are describing the normal form of the data, not it’s access patterns based on actual use cases. It is never the case that implementation “should” reflect anything but usage requirements.
👍 1
evoskuil04:38
replied to a thread: view
Then query for it by its hash. But again, what you personally would like is not what drives our design.
evoskuil04:41
replied to a thread: view
Yes, because it is not only useful but is facilitated by the fact that we never delete data (so low cost). This is not the same as navigating children.
evoskuil04:56
Libbitcoin does not exhibit the recent bitcoind (Core, et. al.) consensus bug or DoS bug pertaining to internal double spend checks. As these checks do not require chain state they are performed in a context-free manner.
👍 5
M
Mlmikael05:31
👍👍👍

Sunday, September 23, 2018

neillm21:28
Reserve Currency Fallacy (Baltic Honeybadger 2018): https://www.youtube.com/watch?v=66ZoGUAnY9s&amp;t=2147
👍 1

Monday, September 24, 2018

skaht00:22
Where is the equivalent of static const int COINBASE_MATURITY = 100; https://github.com/bitcoin/bitcoin/blob/master/src/consensus/consensus.h#L19 within libbitcoin?
GitHub
Bitcoin Core integration/staging tree. Contribute to bitcoin/bitcoin development by creating an account on GitHub.
neillm00:23
GitHub
Bitcoin Cross-Platform C++ Development Toolkit. Contribute to libbitcoin/libbitcoin development by creating an account on GitHub.
skaht00:23
Thanks
skaht01:44
Is it fair to say libbitcoin did not suffer from CVE-2018-17144?
neillm01:45
@skaht Yes
skaht01:49
Doing a little horn tooting about the need for diversity to Bitcoin Core.
skaht02:06
Looks like all those other language transcriptions of Bitcoin Core versions 0.14.0 up to 0.16.2 in different languages will need to be updated.

Thursday, September 27, 2018

S
shota11:52
Hello guys, I have a simple question. can anyone explain how to generate scriptPubKey from given address ?
neillm12:01
GitHub
Bitcoin Cross-Platform C++ Development Toolkit. Contribute to libbitcoin/libbitcoin development by creating an account on GitHub.
GitHub
Bitcoin Cross-Platform C++ Development Toolkit. Contribute to libbitcoin/libbitcoin development by creating an account on GitHub.
S
shota12:04
I read all of that but in those examples they always assume hat previous output is always pay to key hash. there is no checking according to address structure what kind of scriptPubKey is required ....
(edited)
neillm12:06
The part pointed out generates a script for a destination address
S
shota12:11
yes, but only for pay to key hash pattern ...
neillm12:12
If you look at the second link i sent, the next method is for other patterns
S
shota12:13
let's say you are given an address. how can you check if address is paying to witness hash script (and scriptPubKey will be (00) + (32 bytes of hash(witness script) ) ) or not
building scriptPubKey for sending to segwit address isn't given there or I cannot find it
neillm12:19
I'm not the best person to answer here, but if given an address only, I don't know if you can make that determination. You need the script (or full tx that contains it) to determine that
S
shota12:20
so when you are the one who should make that transaction it's difficult 😄
neillm12:25
GitHub
Bitcoin Command Line Tool. Contribute to libbitcoin/libbitcoin-explorer development by creating an account on GitHub.
The first step of spending (i.e. making the transaction) is retrieving that previous transaction so that information should be known. I was thinking the scenario was offline, like handed an address on a piece of paper.
S
shota12:32
that's what I'm looking for. creating transaction without access to blockchain.
neillm12:35
My hesitation on some witness addresses is that I think they are indistiguishable from P2SH or multisig, just by looking at them (could be wrong there). In any case, I don't think that's true of all witness addresses, particularly those that are obvious (bech32 encoded)
S
shota12:36
that's the address format for segwit
GitHub
Bitcoin Improvement Proposals. Contribute to bitcoin/bips development by creating an account on GitHub.
neillm12:44
As for creating transactions without access to the blockchain ... I don't understand the purpose but ... I think the only way to do that is to ensure that you are the only one sending/receiving between yourself onchain, and even then, you can't know if any are ever confirmed. Maybe you have a better scenario in mind?
Z
zoranc15:24
i am rebuilding libbitcoin with the install script on ubuntu 16.04. now when i try to build my project i get missing symbols for the libsecp256. adding -lgmp on the command line fixes it. don't see much changes in the install scripts, besides new boost and new zmq...
neillm15:32
Hrm, that shouldn't be necessary. Check if there's a shared library conflict, or try to build statically
Z
zoranc16:25
all the libraries are static (built it with --disable-shared) and still the same issue. not sure how to check for a shared library conflict...
neillm16:26
If you built bs or bx, just use ldd
Hrm, yeah, actually it looks like libsecp256k1 relies on gmp
At least, I see gmp symbols in the statically built library on my system
Looking at the config.log for the secp256k1 build, I see it selecting the system gmp for bignumbers. I would think that's system specific, but given that it's on my system too, it might be the norm.
neillm16:40
@pmienk may be able to chime in. Requiring a user application to additionally add -lgmp instead of just using the pkg-config --libs is a small extra step, but I guess it's an extra step. Perhaps it's not possible to detect which bignum library the secp256k1 build chose and therefore it isn't assumed?
Z
zoranc16:41
both bx and my app (built with -lgmp) show all fine. can't check my other linux box right now. but i didn't recall having that issue
neillm16:42
Anything built statically (bx/bs) should be shielded from this. The case I'm talking about is building an external application that uses libbitcoin, which uses libsecp256k1, which may or may not be using libgmp
Am I following your original question properly?
Z
zoranc16:45
i have external application that uses libbitcoin (hence libsec256k1), it seems to be linked statically (both my app and the libbitcoin libraries)
neillm16:46
Right, but is the libsecp256k1 linkage to gmp also static? It appears to not be, if you have to specify it
Z
zoranc16:51
correct!
pmienk18:13
That might be my mistake. I don't believe on static linking we're properly forcing pkg-config to invoke with --static, which may fix the problem.
neillm18:14
@pmienk Cool, didn't know about that option, but adding --static to the pkg-config line does appear to include -lgmp on my system
pmienk18:15
i ran into this a while back thanks to cmake work, but wasn't thinking to add it to autotools. will augment
👍 1
neillm18:16
@zoranc In the meantime, give that a go
pmienk20:41
before i go digging through secp's config/make/etc, anyone know why they're getting a dependency on gmp?
evoskuil20:49
It’s an optional perf optimization I believe.
pmienk20:49
autodetected it seems
looks like we can either have automake throw error when enable_static and enable_shared or we can use the static libs whenever enable_static. I'm testing variations

Friday, September 28, 2018

Z
zoranc11:27
adding --static to each pkg-config line fixes the problem too, looks better than adding -lgmp