this was a most hard to find and hard to debug issue, bcz sometimes
iguana did splitfunds correctly and sometimes not. nobody tried to
help me to catch the "wrong state" in which it fails, despite all
provided instructions. i spent all night along to catch the state
of utxos in which splitfunds guarantee fails. so, i have only wallet.dat
state and just every acsplit try fails on it. this was a half of victory.
second stage was debugging iguana and komodod sources, adding printouts
for preimage calculation, printouts for hashes, printouts for everything,
launching gdb under VSCode and other things. and after spent ~24 hours
of continuous work i found root of the issue.
it was in spendamount (!) ... i found that dpow_gettxout returns
34.26707593 in "value" field. but after conversion to uint_64 it becomes
34.26707592 . for non-sapling enabled chains seems nothing hurts, but
since sapling activated in KMD and assetchains it's significantly.
bcz according to zip-243 https://github.com/zcash/zips/blob/master/zip-0243.rst
amount field is a part of preimage calculation. and as we have
wrong spendamount we have a wrong sighash when calc crypto_generichash_blake2b_salt_personal
with sig_hash_personal = ZCASH_SIG_HASH_SAPLING_PERSONALIZATION .
Look at the "Test vector 3" in ZIP-243 and amount field in preimage and
you will understand the bug.
Sometimes double -> uint64_t was fine and splitfunds is success, but
sometimes (depends on double representation of value) it was wrong and
splitfunds fails. That's why it was so hard to catch and fix.
But now, seems the issue is fixed!
earlier we have fixed size buffer for outputs uint8_t outputs[1000]
(derived from markemaker source), and this causes problems when we
try to split over 22 duplicates, bcz in this case outputs array size
overflows 1000 bytes. now memory for array allocates dynamically,
depends on actual outputs size.