zips/drafts/bitcartel-nu0-tx-format/draft.rst

208 lines
8.5 KiB
ReStructuredText
Raw Normal View History

::
ZIP: ???
Title: Network Upgrade Zero ("OverWinter") Transaction Format
Author: Simon Liu <simon@z.cash>
Comments-Summary: No comments yet.
Category: Process
Created: 2018-01-10
License: MIT
Terminology
===========
The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119.
"Legacy" - pre-NU0
"NU0" - Network upgade zero
"Overwinter" - Code-name for NU0
Abstract
========
This proposal defines a new transaction format required for Network Upgrade Activation Mechanism [#zip-0???]_
and Transaction Expiry [#zip-0???]_.
Related to [#zip-0143]_
Motivation
==========
A new transaction format is required to:
* support safe network upgrades as specified in Network Upgrade Activation Mechanism [#zip-0???]_.
* provide replay protection between Legacy and Overwinter network upgrade.
* provide replay protection between different branches post-Overwinter e.g. Overwinter and Sapling upgrade.
2018-01-25 23:30:32 -08:00
* enable a branch to support multiple transaction version formats.
* ensure transaction formats are parsed uniquely across parallel branches.
* support transaction expiry as specified in the Transaction Expiry [#zip-0???]_.
Specification
=============
Zcash launched with support for upstream Bitcoin version 1 transactions and a custom version 2 transaction format which added fields required for shielded transactions.
======== =============== =========================== =======
Version Field Description Type
======== =============== =========================== =======
2018-01-25 14:59:05 -08:00
>= 1 version positive value int32
>= 1 in_count varint 1-9 bytes
>= 1 tx_inputs list of inputs vector
>= 1 out_count varint 1-9 bytes
>= 1 tx_outputs list of outputs vector
>= 1 lock_time block height or timestamp uint32
>= 2 nJoinSplit varint 1-9 bytes
>= 2 vJoinSplit list of joinsplits vector
>= 2 joinSplitPubKey joinSplitSig public key 32 bytes
>= 2 joinSplitSig signature 64 bytes
======== =============== =========================== =======
Version 1 and 2 transaction formats are legacy formats.
Version 3 transaction format will be introduced for Overwinter.
The version field must have its most significant bit set.
There will be new fields for:
* branch id
* expiry height
======== =============== =========================== =======
Version Field Description Type
======== =============== =========================== =======
2018-01-26 00:24:28 -08:00
>= 3 version must have MSB set int32
2018-01-25 14:59:05 -08:00
>= 3 branch_id branch/fork identifier uint32
>= 3 expiry_height block height uint32
>= 1 in_count varint 1-9 bytes
>= 1 tx_inputs list of inputs vector
>= 1 out_count varint 1-9 bytes
>= 1 tx_outputs list of outputs vector
>= 1 lock_time block height or timestamp uint32
>= 2 nJoinSplit varint 1-9 bytes
>= 2 vJoinSplit list of joinsplits vector
>= 2 joinSplitPubKey joinSplitSig public key 32 bytes
>= 2 joinSplitSig signature 64 bytes
======== =============== =========================== =======
Transaction Version
-------------------
The version field is always serialized in little-endian format.
Version 1 transaction 5c6ba844e1ca1c8083cd53e29971bd82f1f9eea1f86c1763a22dd4ca183ae061
2018-01-26 00:26:36 -08:00
* begins with 0x01000000
* 32-bit signed integer 00 00 00 01 == 1
Version 2 transaction 4435bf8064e74f01262cb1725fd9b53e600fa285950163fd961bed3a64260d8b
2018-01-26 00:26:36 -08:00
* begins with 0x02000000
* 32-bit signed integer 00 00 00 02 == 2
2018-01-26 00:24:28 -08:00
Legacy parsers require the transaction version number to be positive.
2018-01-26 00:24:28 -08:00
Overwinter parsers also require the transaction version number to be positive, however the serialized version field must have the most significant bit set.
2018-01-26 00:24:28 -08:00
By setting the most significant bit of the version field, we ensure there is replay protection between Legacy and Overwinter compatible software. With two's complement integers, the most significant bit indicates whether an integer is positive or negative, therefore Overwinter version fields will be negative.
2018-01-26 00:24:28 -08:00
Consider the following example:
2018-01-26 00:24:28 -08:00
When serialized, a Version 3 Overwinter transaction will take the form:
2018-01-26 00:26:36 -08:00
* Little endian format: 0x03000080
* Representing a 32-bit signed integer: 0x80000003
* Which has a decimal value of: -2147483645
2018-01-26 00:24:28 -08:00
Legacy parsers will expect the version to be a positive value, such as 1 or 2, and will thus reject the Overwinter transaction as invalid.
2018-01-26 00:24:28 -08:00
Overwinter parsers will accept the transaction as valid as the most significant bit of the 32-bit signed integer has been set. By masking off (unsetting) the most significant bit, the parser can retrieve the actual transaction version number::
2018-01-26 00:24:28 -08:00
0x80000003 & 0x7FFFFFFFF = 0x00000003 = 3
2018-01-26 00:24:28 -08:00
Existing code can continue to check the transaction version using greater than comparison operators::
2018-01-26 00:24:28 -08:00
if (tx.nVersion >= 3) {
for (int js = 0; js < joinsplits; js++) {
2018-01-26 00:24:28 -08:00
Existing tests can continue to set tx.nVersion to zero as an error condition::
2018-01-26 00:24:28 -08:00
mtx.nVersion = 0;
// https://github.com/zcash/zcash/blob/59de56eeca6f9f6f7dc1841630d53676075242a5/src/gtest/test_mempool.cpp#L99
2018-01-26 00:24:28 -08:00
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-version-too-low", false)).Times(1);
// https://github.com/zcash/zcash/blob/30d3d2dfd438a20167ddbe5ed2027d465cbec2f0/src/gtest/test_checktransaction.cpp#L99
Currently, the nVersion field is a public member variable which can be accessed directly. As part of implementing Overwinter, the nVersion field will be made private with access restricted to using getters, e.g.::
2018-01-26 00:24:28 -08:00
bool isLegacyFormat() // return true if the most significant bit of nVersion is unset
int32 getRawVersion() // return version field, -2147483645
int32 getVersion() // return version number, -2147483645 (Legacy), 3 (Overwinter)
Forwards Compatibility
----------------------
A branch may support many transaction version formats. For example:
* Zcash reference implementation, branch "Zcash", versions 3, 4.
* Fork of Zcash, branch "Clone", versions 3, 4*
Where transaction format version 4* for the "Clone" branch might be substantially different from the expected transaction format version 4 for the "Zcash" branch.
Given forwards compatibility, we want the "Zcash" branch nodes to accept transaction version 4, whilst rejecting version 4* transactions which are intended only for the "Clone" branch.
To achieve this, Overwinter requires a transaction to include a branch ID, to explicitly state which branch of the network this transaction is intended for.
Overwinter introduces a new signature hashing scheme which includes the branch ID, but by including the branch ID into the transaction format, clients can quickly reject transactions during deserialization without having to check signatures.
A simple way to filter transactions might look like this::
if (tx.branchID != CLIENT_BRANCH_ID) { ... }
However given that a branch may support a set of transaction version formats, we should implement such that we can write code like::
if (isBranchSupported(tx.getBranchID())) { ... }
if (tx.isSupportedBranch()) { ... }
Overwinter will introduce a method for developers to easily specify and update a map of supported branch IDs and transaction versions which can be easily accessed throughout the system.
Deployment
==========
This proposal will be deployed with the Overwinter network upgrade.
Testnet:
Mainnet:
Backward compatibility
======================
This proposal intentionally creates what is known as a "bilateral hard fork" between Legacy software and Overwinter compatible software. Use of this new transaction format requires that all network participants upgrade their software to a compatible version within the upgrade window. Legacy software will treat Overwinter transactions as invalid. Overwinter compatible software will reject legacy transactions. Once Overwinter has activated, nodes will only accept transactions based upon supported branch ID and transaction versions.
Reference Implementation
========================
TBC
References
==========
Design hard fork activation mechanism https://github.com/zcash/zcash/issues/2286
.. [#zip-0???] Network Upgrade Activation Mechanism
.. [#zip-0???] Transaction Expiry
.. [#zip-0143] Transaction Signature Verification for Overwinter