Remove the last 10 blocks one-by-one from the end of the internal linked
list of blocks, instead of rebuilding a truncated list from scratch.
(This all takes place within a write-lock anyway, so it's atomic.)
Add missing synchronisation to the 'toProtoMessage' method, by first
copying the internal list of blocks inside a read-lock, prior to
serialisation (still outside the lock, to maximise concurrency). Since
we only make a shallow copy, this should be fast and take no more than a
MB or so of extra memory.
This prevents a race seen to cause a ConcurrentModificationException
during store persistence, that sometimes occurred when the application
resumed from a long suspension.
Now that 'mockito-junit-jupiter' has been added to the build test
dependencies, we may replace the manual setup & tear down of a Mockito
session with the 'MockitoExtension' JUnit 5 test extension, as the old
Mockito JUnit 4 test runner was no longer available upon upgrading to
Jupiter. This slightly simplifies the tests which use '@Mock', '@Spy',
etc.
Fix inspection warnings and other minor defects (unchecked casts, bad
'assert*' usage, unused assignments/declarations, missing null checks,
object equality on enum instances, needless statement lambdas, missing
final, redundant 'toString', needless visibility) in 'TxValidatorTest'.
Also, uniformise and slightly tidy resource loading in other test
classes, replacing 'Files.readAllBytes' with Java 11 'Files.readString'
(which assumes UTF-8 as desired, instead of the default charset).
Fix resource loading in 'MakerTxValidatorSanityCheckTests', which breaks
when the working directory has spaces in its absolute path, due to the
fact that the test resource paths are URL encoded.
(This pattern is already used to load resources in a few other tests, so
there hopefully won't be a regression on Windows.)
The `checkFeeAmountBTC` method looks up the `value` field of the
`vin[0].prevout` field without checking whether `vin[0].prevout` exists.
When the field is missing `JsonElement jsonVIn0Value =
jsonVin0.getAsJsonObject("prevout").get("value");` (line 193) throws a
NullPointerException.
The `TxValidator`s `getVinAndVout(...)` method assumes that
`json.get("field").getAsJsonArray()` returns null when the field is not
a JSON array. The `getAsJsonArray()` throws an `IllegalStateException`
exception, however. The `IllegalStateException` doesn't get caught by
any caller.