Skip to content

Instantly share code, notes, and snippets.

@antiochp
Last active April 15, 2020 07:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antiochp/8fcdf7c0ee10dc004ebe03ece37d8091 to your computer and use it in GitHub Desktop.
Save antiochp/8fcdf7c0ee10dc004ebe03ece37d8091 to your computer and use it in GitHub Desktop.
Unknown Kernels

Transaction kernels "feature" is specified as the first byte.

Add a new "unknown" kernel variant for all kernel feature byte >= 4.

  • Plain: 0 (00000000)
  • Coinbase: 1 (00000001)
  • HeightLocked: 2 (00000010)
  • NoRecentDuplicate: 3 (00000011)
  • Unknown: >=4 (00000100..11111111)

Kernel features [0, 1, 2, 3] are implicitly sized, based on the kernel feature.

For example a NoRecentDuplicate kernel -

1 byte | 8 bytes | 2 bytes | 33 bytes | 64 bytes
feature | fee | relative_height | excess commitment | signature

Kernel features >= 4 are unknown and must be explicitly sized. The two bytes immediately following the feature byte specify the size (u16) of the additional data, excluding the excess commitment and the signature.

[Is a u16 the right thing to use for size here? Would u8 potentially be sufficient?]

1 byte | 2 bytes | [size] bytes | 33 bytes | 64 bytes
feature | size | additional data | excess commitment | signature

This allows "unknown" kernels to be supported as the explicit size would allow them to be correctly serialized/deserialized.

The kernel signature message would include both size and additional data, as raw bytes, regardless of content -

Hash(feature | size | additional_data)

Consensus rules would still apply. The signature could still be verified against the excess commitment.

What about fees?

The above would simply treat an unknown kernel as having 0 fees. For a transaction to be valid it would need to contain at least additional kernel specifying the correct fee.

Alternatively we could support unknown kernels with optional fee via one of the bits in the feature byte. An unknown kernel with fee bit set would treat the first 8 bytes of the addtional data as the fee (u64) and the remainder as opaque. An unknown kernel with the fee but unset would treat the full additional data as opaque.

Feature 4 (00000100) would be an unknown kernel with 0 fee. Feature 5 (00000101) would be an unknown kernel with fee specified in additional data (first 8 bytes). etc.

This would allow unknown kernels to participate in the fee related consensus rules while still allowing for the possibility of future unknown kernel variants that do not have an associated fee.

This would allow for "softfork" compatible future kernel variants.

Existing nodes would simply treat additional data as opaque yet still support kernel signature verification. Softfork nodes would be able to parse additional data and apply additional consensus rules.

For example we could introduce a DeadBeef kernel variant via the "unknown" feature byte 00000100. Existing nodes will treat additional data as opaque and simply verify the kernel signature. Softfork consensus rule states the first 8 bytes of additional data must be DEADBEEF.

Alternatively this could be introduced via the feature byte 00000101 with the kernel including a fee. Softfork consensus rule states the first 8 bytes of additional data represents the fee followed by DEADBEEF in the next 8 bytes.

@tromp
Copy link

tromp commented Apr 12, 2020

I would like to think that 1 byte is enough as length specifier.
I'm worried that once we allow kernel features 4..255, that someone will put then on-chain just for fun.
Once that happens, we would no longer be able to assign new semantics to them, as those semantics may be violated by existing occurrences.
I wonder how bitcoin deals with that when they soft-fork one of the remaining NOP instructions. I guess they just pick a threshold height and say, before that height it's a NOP, while after that height it's such-and-such. Ok, that would work for us too....

@antiochp
Copy link
Author

I guess if we were to recreate the full spam resistant NSKR kernel variant we would need the following additional data -

  • relative height (2 bytes)
  • referenced excess commitment (33 bytes)
  • signature (64 bytes)
  • fee (8 bytes)

So a total of 107 bytes additional data.

1 byte for the length would be more than sufficient for that.

@antiochp
Copy link
Author

One significant downside that was discussed in the dev meeting is spam.
It would appear that allowing for future kernel variants would by definition allow arbitrary data to be included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment