About the Grin Node(s)

Hi, I’m new to the forum (no ipollo for me, xd) but I’ve been following Grin since the very beginning (before that I was watching monero).
Disclaimer: I really like Rust and I trust and listen to the compiler (maybe too strictly) but my formal education and job is not related to CS.

Recently I’ve been reading the public technical discussions and I feel compelled to ask about something that maybe a lot people are thinking but not vocalizing:

Exactly what is the technical huge advantage of having “several” nodes or language implementations of the same consensus code? (not code simply calling the rust API but real new core code written in… Go, for example)

We all, for sure, can see the disadvantages listed here (with some vulnerabilities linked to btcd, others to Bitcoin Core, etc.:

I know this is, maybe, a controversial topic but I’ve search for answers and found none, I really hope someone with more knowledge would be willing to shed some light about this concern I have.


The main advantage is improved odds of exposing implementation bugs.

Other advantages include attracting more developers, who might find a codebase in their favorite language much easier to understand and work on.


@tromp is correct. I’ve found a number of bugs in GrinMW while working on Grin++ and vise-versa. It gives you greater confidence that the protocol follows a spec, rather than being the spec (as is the case with bitcoin with its many quirks).

And for me, an even bigger advantage is decentralization. Multiple dev teams competing to improve Grin leads to better quality and resilience to attacks. See also: https://twitter.com/Narodism/status/1352238840854040576


Thanks for your reply. Regarding your first advantage, looks like memory-safety implementation bugs are the most difficult to deal with and Google is now literally giving free money to rewrite code in memory-safe programming languages, i.e. rust.

Thanks for your reply. Correct me if I’m wrong buy I thought that Grin is one possible implementation and the spec is the paper described here in detail:

The most important thing here is security, right? OK, now I only have to understand X lines of well commented Rust code. Later, with “several” nodes, if I really want to judge the security of Grin, I’ll have to read the source code in Rust, Go, Php, brainfuck…
fwiw, I only see the surface attack growing and literally no one to trust…

You can read the source of the one you use. The correctness of other implementations is irrelevant from your point of view since you’re not running that code.

It’s a double-edge sword. As was mentioned already, multiple implementations are good for finding mistakes. They can also come at the cost of network splits if one of the node implementations has a bug that was not found. Another thing is security audits where ideally you’d have a single really well tested and audited wallet backend and everything else was using this for wallet operations. This is also why some of us were cheering for a mobile wallet that uses grin-wallet backend - you really don’t want the wallet creators to deal with this and hope they get it right. All node implementations also need to be maintaned or the users might be forced to switch. For instance, if one of the implementations added PIBD and the other did not, then you’d have a “split-brain” sync forever. So there are both pros and cons to both approaches, but in any case, whatever you end up using, you want it to be audited. An extreme case would be separating the consensus rule checking, wallet output generation, signing, validation in a separate package that both the node and the wallet backend use. This package is then never touched and if it is, it is reaudited along with the consumers of this functionality.


Thanks for your reply. I agree with what you say but, to be honest, I only see one edge in that sword.
I really don’t want to sound like I’m trolling but I must be very dumb, cause, to me, the so called “advantages” are some kind of joke:

  • Finding mistakes/bugs: Yeah, but what about the null pointers, dangling pointers or data races that rust ownership prevents by default? (that’s why you need to talk with the compiler about life, ahem, -times) Also, bitcoin quirks are really C++ quirks, right? So now, to begin with, there are two kinds of quirks. No, no. The only way to find some nasty bugs is to write a new batch of LOC and maintaining them, sine die (and then, I suppose, following this logic, it will be needed to write this code, once again, in rust, so we can find the fresh bugs in them, right? It’s turtles all the way down…).

  • Multiple dev teams competing (a.k.a. The Hunger Games): Yess, what about multiple teams writing code that talks to the official API or multiple teams writing rust? Decentralization == Multiple programming languages for the consensus code? I just don’t get it.

Imagine you have 3 implementations, rust, c++ and go. Let’s say one has a bad block validation (eg can produce hidden inflation). If all 3 implemetations are 1/3 of all nodes then majority will reject such block and it will converge to the non-inflated chain. I’m not an expert in rust or c++ but yeah, i guess rust compiler is more helpful, but there are also some other languages which have great typing system and therefore compiler can help you a lot (eg. haskell). So decentralization here is in terms of how many different node implementations need to fail at the same time to get some unwanted chain which in my example would be 2. Btw golang is great from another point of view - it’s so simple that it makes it easy to contribute to and read/understand the code. In rust you must first learn many rust-specific things which means less eyes on the code

I’ve written some Golang code, the problem is the runtime garbage collector and rob-commander-pike taking power out of the programmer and into his hands. But the syntax is really nice and Russ Cox is incredible :slight_smile:
Haskell… yeah >.<

I think it’s similar as with dynamically vs statically typed languages. Static languages can be thought as having compiler write automated tests for types. Similarly, borrow checked can be seen as an additional package of tests that are done by the compiler that resolve dangling pointers etc… Since most of the security bugs are memory related (70% in chrome), this means that the largest class of security bugs mostly go away. But you still need to be careful. And it’s easier to make mistakes in a language you’re not comfortable with, so using Rust isn’t necessarily a good choice, it depends on what the devs know as well. But I do think this was a great choice for Grin.

Yeah, this was the best choice. That is why I don’t understand the current situation. But I get that sometimes rust feels like

There’s nothing wrong with someone writing a new node implementation. Anyone can write a node in Go and people would be free to use it. You can’t really prevent this. This can even serve as a nice way to get to know Grin in and out to later contribute to one of the other clients.

You’re talking about 2 different things here. First you asked about multiple implementations, which is what we responded to.

But now you’re arguing about coding languages, which is fine I guess, but we’re now off topic. So all I’ll say about language choice is that rust does solve some security issues, but modern C++ also does with a far less annoying compiler :slight_smile:

Btw, bitcoin’s quirks are not from C++, but from awkward script design and database choices.

1 Like

I’m sure that you can write concurrent code in modern C++ 100% free of bugs (maybe others won’t because the compiler does not force them to).
I first asked about the technical advantages, and I still think that the two provided (less bugs and human resources/competition) are false.
I compare the two code repositories and I see one where you wrote 99.9% of the code (unless you are, in reality, anonymous and your account is managed by several people), in the other repository, the one I’ve been following since the beginning, I see more security.
Well, my conclusion is that, for security reasons and to attract new developers, the rust repository is better suited and that having two parallel things going is just nuts. As simple as that. More eyes watching the bazaar since inception, right?
Reading your last short answer makes me believe that you don’t want to get deeper into this off-topic and that you considered it solved. But maybe others, like me, need some public clarification about this concurrent-consensus++ thing.

No, you see more contributors. The 2 are not the same.

Sure, but despite all of those eyes on it, the rust implementation remained unusable and painfully slow for years. Similarly, libbitcoin remains a far better implementation than bitcoinqt is. There are more factors to consider than just number of eyes on a project.

I’m the one apparently needing clarification. I thought this post was a generic discussion about the pros and cons of multiple implementations, but you seem only wanting to discuss GrinMW(Rust) and Grin++ (C++). If you want to claim the rust one is more secure, that’s fine by me. But that doesn’t invalidate the thesis that multiple implementations improve each other.

Two implementations also create a bit of healthy competition. Two teams creating different implementations is much better than one implementation without any developers that are motivated to contribute.