TRB 'Cement' Draft Review

Filed under: TRB — cgra @ 14:14:48

For inclusion in TRB, a feature was proposed, that I intend to comment on in this article.

Sync speed hypothesis

Based on looking at the code, my hypothesis of the expected time the cement sync would take, is: verification time + peer-average transfer time.

By peer-average here, I mean the average determined by all of the uploading peers' upload speed, weighted by the amount of participation. A detailed explanation follows:

Sync mechanics

At startup, vNodes is empty, until populated with peers a connection was established as the first. More peers may be added later.

On sync start, or on a peer lock-in break, cement sync continues with "one of the peers in vNodes".

Which one of the peers in vNodes, it depends on:

1) Whether cs_vSend is locked for a peer or not (outgoing data being handled at the same time (here and here) , or not), and either allowing SendMessages() processing at that moment, or not.
2) Message handler thread loop timing (spins through vNodes repeatedly, 100 ms delay in-between).
3) The order the peers ended up into vNodes in.

The sync "tends to" lock-in to a single peer, because when a block is accepted from peer, next block's AskFor() schedule starts off with the same peer. The first AskFor() of an item always "executes immediately", and further requests for the same item are only scheduled for later, in 2-minute intervals.

The lock-in may still break, though, if the locked-in peer's cs_vSend happened to be locked at a specific moment. The lock-in can also break, if peer fails to send the block before another, later-scheduled peer does.

When the lock-in breaks, the sync continues with the "one of the peers in vNodes", similarly as it started off with.


The effects of the occasional lock-in breaks by the cs_vSend being locked at specific moment, and peer failing to deliver the block in time, are assumed to average as random over time. This in turn would effectively randomize the block-sending peers, and hence, every peer we're connected to, get to affect our download speed equally.

How often will the peer lock-in break occur, though, I have no estimate of.

Slightly spammy AskFor()-scheduling

The mapAskFor of each peer may extend up to 10 * peer count / sec, for 2 minutes, until the currently expected block is received and accepted. Extending happens only during download-time, and not while verifying a block.

In a rough worst-case scenario, this could mean 10 * 125 * 2*60 * (8+4+32) ~ 6 MB of excess mapAskFor items.

In the light of 1) what other spit-spaghetti TRB consists of, and 2) not immediately knowing any obviously better approach, this kind of issue may not call for immediate action, but perhaps worth knowing still.

Cement loading

The loadcement RPC-command's help text should mention the cement to be loaded must be in ascending order, and continuous, even if loaded in multiple batches.

About the validation in Cement::load():

1) It should say it explicitly, when the problem is a gap. Accidental gap, when feeding multiple cement files could get hard for the operator to notice.
2) Why not just stop the cement loading, immediately on any occurred problem?
2a) A gap in cement will cause possibly a large part of the cement to get dumped into console/debug.log, for nothing.
2b) Any kind of "natural rot" error is effectively also a gap, causing also an unwanted console/log dump.

With the above changes, two further points are worth noting:

1) Cement::load() summary can now state a (better informing) height range, instead of a simple, loaded hash count.
2) The gap check in Cement::verify() is now possibly redundant.

Other notes

When the classical mining is enabled, ProcessBlock() is used to self-validate new blocks. Cement-validating new, unpublished blocks doesn't make sense. The cement mode, and mining mode should be mutually exclusive.

I refrained from commenting the thread lock earlier, but now feel ready for it: The thread lock is necessary for the cement functionality, as it currently stands. RPC-commands are processed by one thread, and incoming messages by another. Without the lock, one race condition example would be:
The operator could be loading more cement from a file, while an incoming block was being checked against the cement. Also, the miner thread may trigger a cement verification, even though it shouldn't.

Somewhat inconsistent naming is used, and possibly could be improved: "permitCement", "cementPermitted", "mayLoadCement", and  "-cement"; all meaning the exact same thing: Whether the cement-mode is enabled or not.



  1. Thanks for reviewing; quite good points, esp. in re: ProcessBlock.

    Comment by Stanislav Datskovskiy — 2022-02-20 @ 15:15:25

  2. trb no more? address not loading...

    Comment by reviewer — 2024-01-08 @ 4:04:26

  3. reviewer, see here and here, currently only works.

    Comment by cgra — 2024-01-09 @ 7:07:10

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by a less-enormous pile of '???'