If this is the retained choice with respect to the replay attacks (who knows! maybe we will respect users) here is a proposed solution.
- Two users want to make a transaction.
- They look at the current block height of the Grin blockchain, represented by the integer
- They sign the transaction with
signature_block_heightin the signature’s message of the kernel excess.
- Similarly to kernel offset, they join
signature_block_heightwith their transaction (of course, unlike kernel offset,
signature_block_heightis not to be aggregated).
- Transaction enjoys some time in the mempool up to
inclusion_block_heightis the block at which the miner includes the kernel in the blockchain (precisely, he includes it in the kernel MMR).
Instead of having its leaves on
(kernel), the kernel MMR has its leaves on
(kernel, relative_height). Kernels are still comprised of excess and signature only.
signature_block_height is not included in Kernel and is not onchain data (but just mempool data).
- Miner includes the kernel into the kernel MMR through the leaf
relative_height = inclusion_block_height - signature_block_height.
(i) Grin protocol rules has to set a maximum value allowed for
relative_height, for example call it
(ii) kernel verification rule: Each couple
(kernel, relative_height) corresponds to a unique
inclusion_block_height (visible by verifiers) and is valid (protocol rule) if and only if the signature for the kernel excess is correct for the message
inclusion_block_height - relative_height.
This protocol allows:
(a) Verifiers to verify signatures easily since they directly derive the message of the signature in the leaf of Kernel MMR:
message = signature_block_height = inclusion_block_height - relative_height.
(b) Verifiers to verify efficiently kernel uniqueness on the whole blockchain without the need to keep all the history in memory but a very short history instead; all the kernels belonging to blocks older than
current_block_height - relative_max can be forever removed of uniqueness check, where
current_block_height is the current block height (most recent block on the blockchain).
The method doesn’t change the current composition of a kernel, and stores relative heights rather than absolute heights. Scalability and protocol elegance blows are essentially negligible.
More on scalability of the construction, absolute time locks as side effect, and security are discussed in posts below.