- Removing the sign bit from key images enables an optimization for
fcmp's.
- If an fcmp includes a key image with sign bit cleared,while the
same key image with sign bit set exists in the chain already via a
ring signature, then the fcmp would be a double spend attempt and
the daemon must be able to detect and reject it.
- In order for the daemon to detect such double spends, upon
booting the daemon, we clear the sign bit from all key images
already in the db. We also make sure that all key images held in
memory by the pool have sign bit cleared as well.
- Key images with sign bit cleared are a new type:
`crypto::key_image_y`. The sign bit can be cleared via
`crypto::key_image_to_y`.
- The `_y` denotes that the encoded point is now the point's y
coordinate.
- In order to maintain backwards compatibility with current RPC
consumers, the daemon keeps track of which key images have sign
bit cleared and not, so that upon serving
`spent_key_image_info::id_hash`, the daemon can re-construct the
original key image and serve it to clients.
- If locked output migration step completes, then program exits
while migration step to grow the tree is in progress, make sure
the migration picks back up where it left off growing the tree.
- Make sure db cursor gets set in all cases when renaming
block infn table.
- If the output is invalid/unspendable, upon unlock it will be
deleted from the locked outputs table and then won't be used to
grow the tree. Upon reorg/pop blocks, the invalid output won't be
re-added to the locked outputs table upon trimming the tree. Thus,
it's possible for an invalid/unspendable output to not be present
in the locked outputs table upon remove.
- trim_tree now re-adds trimmed outputs back to the locked outputs
table. remove_output then deletes from the locked output table.
- Since outputs added to the tree in a specific block may have
originated from distinct younger blocks (thanks to distinct unlock
times), we need to store the 8 byte output_id in the leaves table
as well, so that in the event of a reorg, upon removing outputs
from the tree we can add them back to the locked outputs table
in the correct order.
- Reverted back to storing output_id in locked_outputs table; it's
required to make sure outputs enter the tree in chain order I see
no other simple way.
- Removed unnecessary comments and db flags (MDB_APPENDDUP already
makes sure key/value doesn't already exist, and when inserting,
every global output id should be unique, so should never get that
error)
- We must use the output pubkey to calculate key image generator I
- Since torsion cleared outputs can be spent via ring sig today,
if we torsion clear outputs **before** calculating I, then the key
image of torsioned outputs will be different when constructing
fcmp's, effectively enabling a double spend of torsioned outputs
via ring sig before fcmp's and again via fcmp.
- Storing {output pubkey, commitment} instead of {O.x,I.x,C.x} to
save 32 bytes per output.
- Removed call to hash_init_point in constructor
- Replaced global static CURVE_TREES_V1 with a smart pointer
- Don't need to link Rust static lib when including curve_trees.h
- leaves table doesn't need dupsort flags, all leaves should be
unique by key
- rename fcmp -> fcmp_pp
- return when 0 leaves passed into trim_tree
- Can derive {O.x,I.x,C.x} from {O,C}
- Note: this slows down tests since they do the derivation both
on insertion into the tree, and when auditing the tree
- At the hard fork, we don't need to store {O,C} in the
output_amounts table anymore since that table will no longer be
useful
- Replace CLSAGs with a single fcmp_pp
- fcmp_pp is an opaque vector of bytes. The length of the vector
is calculated from the number of inputs on serialization (i.e. the
length is not serialized, only the raw bytes are serialized)
- Includes tests for binary serialization happy path and errors