I am fine either way and slightly prefer the softer approach of capping it to 100 instead of asserting that it is <=100. There was a discussion some time ago about crashing the program way too easily and reserving the assert/crash only for cases where the continuation of the program really does not make sense. I kind of agree with that.
Yes, Assume() is some middle ground between assert() and the softer approach. Assume() + cap in release builds looks reasonable to me too. Plus document it properly: “make sure you never pass >100 or you will crash the program” … hmm, could this end up in all callers doing the cap at the call site before calling GetAddr() to make sure to avoid a crash?
Do you remember the bug number? “The reason max_pct exists is not to reveal the entire addrman”, but then passing even == 100 is a bug?
If you will be touching this, there is this minor mostly theoretical thing: max_pct * nNodes could overflow and I guess max_pct * nNodes / 100 could end up with a lower value than nNodes for some very high input max_pct. So, if you will be touching this, maybe it is “safer” to implement the cap as:
0max_pct = std::min(max_pct, 100);
1nNodes = max_pct * nNodes / 100;
(this occurred to me just recently)