Question about the old inflation bug

Question for the community that has likely been answered… but I can’t find it (don’t have to repeat answer, maybe just send me a link?). Here is the question: I know in 2020 there was an inflation bug found that enabled an exploiter to create unlimited grin. I also know the community responded ASAP and patched the bug. I also understand that the team performed an extensive review of the blockchain’s history to ensure that the bug had not been exploited before the fix.

My question pertains to that last point. Can someone explain how that extensive review of the blockchains history was done and what level of certainty we have that there is only the scheduled amount of Grin in existence? For instance, did exploitation of the bug produce a ‘paper trail’ within the blockchain such that we can know for certain by a lack of ‘paper trail’? If so, can anyone explain what trail we would have expected to see (and obviously don’t see)?

Thanks in advance.

Note: I am very pro grin/mw so this is not intended to dredge up old history in a negative way, rather, I think the answer is of critical importance since the supply is not otherwise auditable so would like to understand it better.

1 Like

One of the two Grin implementations, the rust grin one, failed to properly verify rangeproofs. When this was exploited by publishing transactions with incorrect rangeproofs, they were accepted by grin but rejected by Grin++. The fix was to make rust grin properly verify rangeproofs as well. What you call extensive review of the blockchains history is just wiping out the on-disk chain data and re-syncing from scratch with the fixed code, ensuring that only transactions with correct rangeproofs get accepted.

The supply is audited (balancing of Pedersen commitments) with every sync.

7 Likes

@tromp , thank you for taking the time to reply, it was very helpful. That does help me understand and affirms that we can have certainty that only the scheduled amount of Grin is in existence. I am reading elsewhere to ensure I understand the answer completely and may be back for an additional clarification if I can’t find what I need in existing literature. I had been under the impression that the only remnant of valid transactions could be the kernel such that it was not possible to reconstruct historical transactions other then to calculate/audit that the chain of ‘kernels’ created by the nodes at the time when the nodes did have all the information were valid kernels. This led me to believe that if the nodes were to accept a kernel as valid that was not valid, the parts that make it invalid would be lost to history. There is a lot already written about this part of the process so I’ll read more about it and figure it out.

As for audits. My understanding was aided by footnote 3 of this site (https://phyro.github.io/grinvestigation/why_grin.html). My understanding was that unlike chains like bitcoin, where we can sum the unspent transactions to validate the total balance, grin relies on the soundness of the process of accepting only valid transactions which sum to zero. As such, a grin audit would not calculate the total sum of grin in existence as much as validate that the nodes, given their cryptography, did not create/destroy any grin through means other than the approved means (and thus the balance must be correct by extension).

Thanks again.

1 Like

Indeed the range proofs of spend transactions are not kept by default since there is no need to keep them around to validate the state of the Grin blockchain is correct.
When transactions were included in the blockchain they were validated by both Grin++ (C++) and grin-wallet (Rust nodes) which means the range-proof for each historic transaction was correct and no new coins were created.
Although it is true that in grin there is no need to keep the full history, it is possible by running a so called “archive node”. This can be simply done by changing:

archive_mode = false

to

archive_mode = true

in ~/.grin/main/grin-server.toml (on Linux) or C:\Users\%USERNAME%\.grin\maingrin-server.toml (on Windows).

When enabling archive mode and assuming you are connected to at least one other archive node, you will download the complete history of blocks and transactions and your node will replay all transactions and verify all range-proofs including those of spend transactions.
Every node is in a sense an archive node since it does not trow away old blocks unless you specifically asked it to, but when enabling this mode, your node will try to sync all blocks and will verify all range proofs also of spend transactions.
This takes quite a while (I though 48-72 hours from memory). Optionally you can get a snap shot from someone who runs an archive node if you do not like syncing that long.

Regarding the verification process, if all range-proofs are correct, no new coins beyond the block reward are created. So each nodes verifies the following equations:
transaction: sum(inputs) - sum(outputs) = kernel_excess + fee
______block: sum(inputs) - sum(outputs) = sum(kernel_excess) + 60
_blockchain: sum(inputs) - sum(outputs) = sum(kernel_excess) + height*60

Note that the term blockchain is a bit confusing, since in the case of Grin your node simply validates the above equations. All blocks, the complete blockchain is like one big transaction your node validates as you can see from the equations above.
Thanks to cut-through all spend outputs can be dropped while verifying the equations above. Cut-through is in practice only used to drop spend outputs that already appeared on chain but can in theory be used at the transaction or block level.

Find below a write down of how Grin works that I wrote to help me understand it better. Note that it is the work of an aspiring wizard and might contain imperfections so please also read the referenced sources. :stuck_out_tongue:

Reading about Grin from different authors with different backgrounds is IMO the best way to get a good understanding.

4 Likes

Thanks @Anynomous. I checked my node and, as you predicted, it defaulted to archive_mode = false. I’m curious and might start a new one with archive_mode = true just to see how big the chain becomes.

I read your site and found it helpful. It does seem that given the existence of archive nodes the privacy aspect of the following grin attribute might be a bit oversold.

“This means that all nodes can simply forget an output ever existed once it is spend!. Grin only remembers unspent transaction outputs. This is great for saving blockchain space (scalability) as well as for privacy.”

Grin preserves privacy in lots of ways for lots of reasons, but from what I have just learned about archive nodes, “forgetting outputs ever existed” is not really one of them. Sure, it has benefits for optionally making some nodes smaller that choose to be smaller… but anyone can get that full history at any time so unless I still misunderstand, 'forgetting outputs" is really not aiding privacy. I do understand that the unforgotten spent outputs don’t tell amounts or tie to persistent addresses and so this isn’t really a big concern of mine provided grin gets to the point that lots of transactions are happening within each block. Until then, it seems there is high value in having your UTXO get spent and created in a block with many other UTXO’s being spent/created.

I now am following the logic you and tromp presented above regarding my initial inflation bug question. It is the historical preservation of range proofs associated with every UTXO ever created or spent that enables us to at any time affirm that grin is on schedule with exactly block height * 60 grin. We don’t need to revisit the range proofs in each scan of the “blockchain”, but if we were to ever determine there was a bug in both grin implementations of validation methods, it would always be possible to fix the bug and then playback everything such that we could know for certain if it was ever exploited. (the ability to salvage the situation would then I presume relate to how old the first block containing the exploitation was).

I’ll think about this more as I aspire toward wizarding, but I think I am back on the right track.

1 Like

You are correct. I unfortunately had to fight with core about the need for full archive node support. The lack of support just creates an information asymmetry that gives those who have it extra power. It took some time before it was appreciated and Antioch was awesome for developing the support for archive nodes. I’m grateful for his work.

2 Likes

Having archive nodes is indeed a good thing👍, it creates more trust and certainty in the supply always being 1 grin/second.

I agree that cut-through does not provide any serious privacy benefits for transactions that hit the chain. The real benefit of cut-through is scalability. Both in terms of less space being used by full nodes as well as less computational work being needed to verify the full pruned output set by full nodes. These advantages will only become more significant over time. At the moment the blockchain is compacted by a factor 3x thx to cut-through, this factor will only increase over time.

In theory cut-through can be applied in the mempool or even before broadcasting a transaction. I am quite certain use cases for it will be found and those will have the privacy benefits of cut-through.

1 Like

@johndavies24 and @Anynomous. I agree with you both. Given what I now know, if full archive node status can exist for anyone, then it should be able to exist for everyone. Information asymmetry is not in peoples best interest.

It also creates more trust and certainty in the supply. That inflation concern was in fact is the origin of this post. Fast forward 20 years and suppose grin is in common use as a medium of value exchange, any doubt about the grin supply would be catastrophic. It seems it is these archive nodes that make that possible.

One note about cut-through in the mempool stage. I suppose that could remove any record of intermediate UTXO that are created and spent in the same block, but if my understand is correct the block would always retain full range proof validation of any transaction that used an on chain UTXO or created an on chain UTXO. That data will always be retained by archive nodes and thus the total grin supply could be re-verified. The supply seems pretty secure.

3 Likes

No, it’s the equation

Σ utxo = Σ kernel + offset * G + height * 60 * H

that makes it possible. An archive node doesn’t offer any additional assurances about supply.

1 Like

@CircusDad as tromp already mentioned, you don’t need an archive node to fully validate the supply. The magic of Mimblewimble is that you can forget all the spent outputs (and its rangeproofs) and still validate two key properties we’d want to preserve:

  1. Every output was spent by its rightful owner
  2. Total supply is what we expect it to be (block_height*60 in the case of Grin)

Both properties are verified by the equation tromp mentioned above. To understand how we can know the spent outputs were spent correctly without ever seeing them requires understanding the math behind it, however, if you’re interested in a higher level overview then perhaps Grin | what-is-grin can help clear things up a bit.

3 Likes

Thanks. I did read many pages like that one. Most of the pages abbreviate the range proof portion which must have lead me to believe it was a gate-keeper to getting onto the blockchain rather than something that could be repeated given only what is on the blockchain. I will read it again… I’ll get there eventually. Thanks.