It could be considered standard practice that any type that is designed to represent a concept in the system, should not be allowed to take a value that is invalid for that concept.
The limit was recently removed, and the rationale for it was described as follows:
I think the limit could not be enforced the way it was implemented. It's not enough to check that the value of one Coins
instance is within the limit because what we actually want is to check that the total amount of coins in the network is within limit which is more about the farming algorithm rules. So this check wasn't really useful and kind of provided false sense of security.
The above mentioned things seems to be very different things though.
One thing is to not allow an invalid representation, the other is to "check that the total amount of coins in the network is within limit"
I agree that the latter cannot be done with the former.
But that doesn't disqualify the rationale for the former.
I.e. not allow representing an invalid thing in the system.
I don't see that as providing false sense of security, because it seems obvious to me that checking that network amount is within limit cannot possibly be done that way.
Checking that total amount is within limit, is a completely different piece of functionality. Living somewhere else. But allowing Coins
to surpass the max possible value, is breaking the definition, the domain logic, of what Coins
is.
This is even more true in an interface library like safe-nd
. The Coins
struct will be used in many places. It would have been something else perhaps if it was a very internal piece in safe_vault
for example, where there was an immediate logic some layer above that simply made it redundant.
But here we are providing a data type for external use, that is supposed to represent something very well defined in our system.
If we didn't call it Coins
, but perhaps Amount
, then it would have been something else, because an Amount
doesn't have that boundary defined in our domain logic. But Coins
have very strict boundaries / definition in the system.
And that is regardless of any other enforcing of business rules. (Otherwise, you're kind of coupling it to that business rule, expecting it to exist and cover up that case.)
But that's still off the point, these are two very different things really... so I don't see the connection.
To summarize
Types representing a business object should not be allowed to take invalid values for that object, regardless of any enforcement of other rules, such as "the network should not contain more than this or that limit".
In this case it's obvious that is not enforced in a Coins
instance, since you could just add a multiple of the coins (of any value > 0), to break the invariant about how much should be allowed to exist in the system, since our system has a fixed amount for that, that is not going to change.