-
Notifications
You must be signed in to change notification settings - Fork 124
Description
Recently, the need for append-only attachments came up where multiple faucets may need to add to a note's attachment without being able to overwrite the other faucet's already added data.
I think we can support append-only attachments via arrays relatively easily in the tx kernel.
One of the difficulties with using attachments more generally may be the following:
- A note creator sets
NetworkTargetAccountattachment to make it a network note. - Then an asset is added to that note that requires the faucet callback to add custom data to the attachment. Depending on what exactly the procedure call looks like, this will either fail or it will overwrite the previously set attachment. Both are bad.
In this case, we basically want to allow having both attachments. So the option is to allow multiple attachments per note, or convert the Word attachment into an Array attachment when necessary to make more room.
So, the current output_note_set_attachment tx kernel attachment API could be changed to:
pub proc output_note_append_attachment(note_idx, attachment_scheme, attachment_word_size, ATTACHMENT)
Then it would work like this:
- The note is created and the attachment defaults to
NoteAttachmentContent::None. - A note creator appends a
NetworkTargetAccount(attachment_word_size = 1) attachment to make it a network note. Attachment becomesNoteAttachmentContent::Word, since the data can be represented as just aWord. - An asset is added to the note, issuing faucet is called and it appends its custom data (attachment_word_size = 1) word to the attachment. Now the attachment becomes
NoteAttachmentContent::Array([network_account_target, custom_data0]). - Another faucet adds custom data and the attachment ends up being
NoteAttachmentContent::Array([network_account_target, custom_data0, custom_data1]).
So, the attachment in general becomes effectively immutable and append-only. A nice UX benefit is that the internal representation (none, word, array) does not have to be chosen by the user but automatically by the kernel. In other words, the kernel automatically uses the minimal possible representation.
If attachment_word_size > 1 is passed, the ATTACHMENT is interpreted as an advice map key and the data is flattened and appended.
The downside of this approach is that it wouldn't be possible to overwrite an attachment (which is currently possible). But I'm not sure there are use cases that really require this? So this should be okay.
Another downside is that each attachment needs to set an attachment_scheme and once we have multiple attachments, the space in NoteMetadata is no longer sufficient to encode all of that. So maybe we'll need a header Word per attachment that contains the scheme (and the size of each flattened attachment). Though we can think about ways to make this more efficient by restricting the max number of assets or encoding multiple schemes/kinds into a global header.