-
Notifications
You must be signed in to change notification settings - Fork 877
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
The Great Code Documentation Effort, Part I #1899
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for this documentation. Would have helped a lot one month ago but still helped me right now. I guess there is still a large gap for most people to get onborded
@@ -14,24 +14,10 @@ Getting Started | |||
It's in C, to encourage alternate implementations. Patches are welcome! | |||
You should read our [Style Guide](STYLE.md). | |||
|
|||
To read the code, you'll probably need to understand `ccan/tal`: it's a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It lookes like the hint about ccan/tal is now completely removed. When I first sterted reading the code it was actually helpful for me to know about this particular data structure. Acutally I would rather have enjoyed some more explaination and paterns how to use it. (for example in the beginning I thought ctx is short for commitment tx and not for context was quite confusing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I'll move this to the first occurrence in the code then.
lightningd/lightningd.c
Outdated
* The role of this daemon is to start the subdaemons, shuffle peers | ||
* between them, handle the JSON RPC requests, bitcoind, the database | ||
* and centralize logging. In theory, it doesn't trust the other | ||
* daemons, though we expect hsmd to be responsive. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When being completely new I will wonder what hsmd is. first of all I do not even realize that it is hsm-daemon I don't know wht hsm is and I don't understant why it is cruicial.
lightningd/lightningd.c
Outdated
@@ -18,11 +48,14 @@ | |||
#include <ccan/tal/grab_file/grab_file.h> | |||
#include <ccan/tal/path/path.h> | |||
#include <ccan/tal/str/str.h> | |||
|
|||
/*~ This is common code: routines shared by one or more programs. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
programms or daemons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lightning-cli in at least one case... I've expanded.
lightningd/lightningd.c
Outdated
* It's another one of Rusty's projects, and we copy and paste it | ||
* automatically into the source tree here, so you should never edit | ||
* it. There's a Makefile target update-ccan to update it (and add modules | ||
* if CCAN_NEW is specified). */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe include the removed comments from HACKING.md here?
if (getenv("LIGHTNINGD_DEV_MEMLEAK")) | ||
memleak_init(); | ||
#endif | ||
|
||
/*~ These are CCAN lists: an embedded double-linked list. It's not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if I remember correnctly there are c-macros involved to create such CCAN data structure. As someone new to the project I am confused when to use such macros, if they are autogenerated and how the general process should look like. Maybe we could include a link examples or even provide some small CCAN best practices in a seperate code folder.
on a more meta level: I am not an experienced c programmer. I realize that the CCAN libs seem to ease up stuff but they made the code rather hard to read for me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to simple put an example inline if we need it. Having a single go-to place to read is always better than some out-of-the-way file nobody will read or maintain...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ended up just listing some helpers and fleshing it out a bit more. I'd rather reference them as we see their use. I tried to create a minimal example, but it was contrived and still 20 lines :(
|
||
/* Initialize wallet, now that we are in the correct directory */ | ||
/*~ Our "wallet" code really wraps the db, which is more than a simple |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what more is it?
lightningd/lightningd.c
Outdated
io_poll_debug = io_poll_override(io_poll_lightningd); | ||
|
||
/* Set up HSM. */ | ||
/*~ Set up HSM: it knows our node secret key, so tells us who we are. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as the hsmd was mentioned to be the one daemon that needs to be responsive we should explain this a little bit more here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK.
lightningd/lightningd.c
Outdated
|
||
/* Create RPC socket (if any) */ | ||
/*~ Create RPC socket (if any): now we can talk to clients. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this one is ncessary to have lightning-cli. Maybe it is standard stuff for people familar with rpc but how is such an API exposed (sure over unix domain socket) but where in the code are api calls provided? I guess this doesnot happen in jsonrpc so a hint in this comment would be nice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently the JSON-RPC autoregisters callbacks using the ccan/autodata
module, however that poses some issues if we'd like to use clang
based sanitizers since it does weird things with uninitialized data, so maybe we'd want to ween off that anyway at some point.
lightningd/lightningd.c
Outdated
crashlog = ld->log; | ||
|
||
/*~ The root of every backtrace (almost). */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this the event loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if yes where does io_loop come from? would elaborate here a little bit
lightningd/lightningd.c
Outdated
@@ -482,5 +699,7 @@ int main(int argc, char *argv[]) | |||
memleak_cleanup(); | |||
#endif | |||
daemon_shutdown(); | |||
|
|||
/*~ Farewell. Next stop: hsmd/hsm.c. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is it actually lightningd.c
with a d but hsm.c
without d ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. That's bugged me for a while too, so I renamed them all...
Signed-off-by: Mark Beckwith <wythe@intrig.com>
@renepickhardt Thank youso much for the detailed review. And sorry I didn't write this s month ago :( My initial reservations were that I was using too much space with these comments, but I see that my problem was too little, not too much! I'll go through and create a fix-up using your feedback as a guide... |
lightningd/lightningd.c
Outdated
/*~ There's always a battle between what a constructor like this | ||
* should do, and what should be added later by the caller. In | ||
* general, because we use valgrind heavily for testing, we prefer not | ||
* to intialize unused fields which we expect the caller to set: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "intialize"
lightningd/lightningd.c
Outdated
|
||
/* Get the blockheight we are currently at, UINT32_MAX is used to signal | ||
/*~ Get the blockheight we are currently at, UINT32_MAX is used to signal | ||
* an unitialized wallet and that we should start off of bitcoind's |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "unitialized"
lightningd/lightningd.c
Outdated
|
||
/*~ The core lightning object: it's passed everywhere, and is basically a | ||
* global variable. This new_xxx pattern is something we'll see often: | ||
* it allocates and initializes a new structure, using *tal*, the heirarchitcal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "heirarchitcal"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we call lightningd
the context object, or maybe root of the entire program?
lightningd/lightningd.c
Outdated
* elements, which can be accessed with tal_count() (or tal_bytelen() | ||
* for raw bytecount). It's common for simple arrays to use | ||
* tal_resize(), which is a typesafe realloc function, but as all | ||
* talocations need a parent, we start with an empty array rather than |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "talocations"
lightningd/lightningd.c
Outdated
|
||
/*~ These are hash tables of incoming and outgoing HTLCs (contracts), | ||
* defined as `struct htlc_in` and `struct htlc_out`in htlc_end.h. | ||
* The hash tables are declared ther using the very ugly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "ther"
lightningd/lightningd.c
Outdated
* | ||
* Comments beginning with a ~ (like this one!) are part of our shared | ||
* adventure through the source, so they're more meta than normal code | ||
* comments, and mean to be read in a certain order. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mean -> meant
lightningd/lightningd.c
Outdated
* 'tallocated' off it are also freed. In this case, freeing 'ctx' | ||
* will free 'ld'. | ||
* | ||
* It's incredibly useful for grouping object lifetimes, as we'll see. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"For the technically inclined: tal
allocations usually build a tree, and tal_free
ing any node in the tree will result in the entire subtree rooted at that node to be freed.
Be careful though that a any cycle in the allocation graph may end up causing an infinite loop."
Also for my personal understanding: the allocations are freed in post-order right? (first children, then the parent).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It won't loop on cycles. Freeing is done in two phases: object is marked destroyed, destructor called, then recurse into children, then finally free(object). So destructors are pre-order, deallocation is post-order.
It's common to want to access parents in a destructor (eg. delete from its linked list), so deallocation has to be deferred.
struct ext_key ext; | ||
/*~ Note the use of ccan/short_types u64 rather than uint64_t. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do I always imagine the creepy voice from Portal when the comments speak in first person? :-)
if (chdir(cwd) != 0) | ||
fatal("Could not return to directory %s: %s", | ||
cwd, strerror(errno)); | ||
|
||
db_reopen_after_fork(ld->wallet->db); | ||
|
||
/*~ Why not allocate cwd off tmpctx? Probably because this code predates | ||
* tmpctx. So we free manually here. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought the it's more because the global tmpctx
is an event loop concept and this is outside of the loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but it's before the loop; we tend to allow that elsewhere...
Signed-off-by: Mark Beckwith <wythe@intrig.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We're a daemon. They're subdaemons. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We already have access via the ld object, and we initialized this one twice anyway. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We have a transaction anyway, and it's simpler. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Despite lack of (concrete) acks, I'm going to merge now; it's going to cause rebase hell to delay further, and I'm already itching to post parts II and III :) |
Also, wallet has no business wiring up HTLCs; move that code to peer_htlcs.c. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
fa6fc14
to
a66afbf
Compare
@renepickhardt: why is it actually lightningd.c with a d but hsm.c without d ? And delete unused gossipd/gossip.h. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Code changes: 1. Expose daemon_poll() so lightningd can call it directly, which avoids us having store a global and document it. 2. Remove the (undocumented, unused, forgotten) --rpc-file="" option to disable JSON RPC. 3. Move the ickiness of finding the executable path into subd.c, so it doesn't distract from lightningd.c overview. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Documentation changes: 1. Lots of extra detail suggested by @renepickhardt. 2. typo fixes from @practicalswift. 3. A section on 'const' usage. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Suggested-by: @practicalswift and @cdecker. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
a66afbf
to
20208c8
Compare
Knuth would be proud. Thanks rusty! |
Obviously, I couldn't resist some cleanups along the way. Part II is finished already, but I wanted feedback on this one.
The idea is to walk through the code and along the way point out the techniques and style we use; as it goes on, it will concentrate more on the specifics of the particular daemon. It should be read in order, however.