From c8fac5fb57354c93b78c3a995322838259d341e0 Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 4 Feb 2021 11:42:38 +0800 Subject: [PATCH 1/4] RFC30: Ensure that index < length in input since field using epoch --- ...-ensure-index-less-than-length-in-since.md | 88 ++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md b/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md index e178dcfdd..ce4940a72 100644 --- a/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md +++ b/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md @@ -1 +1,87 @@ -In review, see +--- +Number: "0030" +Category: Consensus (Soft Fork) +Status: Draft +Author: Ian Yang +Organization: Nervos Foundation +Created: 2021-02-04 +--- + +# Ensure That Index Is Less Than Length In the Input Since Field Using Epoch With Fraction + +## Abstract + +This document proposes to fix a bug in the CKB reference implementation. When a transaction input uses the epoch with fraction in the `since` field, the `value` must ensure that the index is less than the length. + +## Motivation + +The `value` part is an encoded number `epoch + index / length`. In CKB, every block is also assigned an epoch number with a fraction. If the block is the `I`th block in the epoch which epoch number is `E` and length is `L`, its epoch number with the fraction is `E + I / L` and `I` must be less than `L`. + +To verify that a transaction is mature since an absolute epoch number with a fraction, the current implementation assumes that `index` must be less than `length` and checks that: + +``` +E > epoch +or (E == epoch and I / L >= index/length) +``` + +This is not consistent when using relative flag in the `since` field, where the `value` is considered as a rational number and added to the cell start epoch. + +This document suggests adding a new rule to verify that when `since` uses epoch as the unit, it must ensure that index is less than the length. + +See RFC17 [Transaction valid since](../0017-tx-valid-since/0017-tx-valid-since.md) for details of the `since` field encoding patterns. + +## Specification + +### Since Absolute Epoch + +When an input `since` field is present, and + +* The `metric_flag` is epoch (01). +* The `relative_flag` is absolute (0). + +Providing that `value` is the encoded number `epoch + index / length`, the transaction is valid only if `index` is less than `length` or both `index` and `length` are zero \*. + +> \* When both `index` and `length` are zero, `value` is converted to `epoch + 0 / 1`. + +If the current epoch number with the fraction is `E + I / L`, the transaction is considered mature when + +``` +E + I / L >= epoch + index / length +``` + +using rational number operations. + +### Since Relative Epoch + +When an input `since` field is present, and + +* The `metric_flag` is epoch (01). +* The `relative_flag` is relative (1). + +Providing that `value` is the encoded number `epoch + index / length`, the transaction is valid only if `index` is less than `length` or both `index` and `length` are zero \*. + +> \* When both `index` and `length` are zero, `value` is converted to `epoch + 0 / 1`. + +If the cell creation epoch number with fraction is `e + i / l`, and the current epoch number with the fraction is `E + I / L`, the transaction is considered mature when + +``` +E + I / L >= e + i / l + epoch + index / length +``` + +using rational number operations. + +## Test Vectors + +When `since` uses the absolute epoch `99 + 360 / 180`, and the current epoch is `100 + 0 / 180`, the transaction is mature using the old consensus rule but is immature using the new rule. + +## Deployment + +The deployment can be performed in two stages. + +The first stage will activate the new consensus rule starting from a specific epoch. The mainnet and testnet will use different starting epochs and all other chains will use the new rule from epoch 0. + +The second stage is optional. After the new rule has been activated, and the blocks in the chain before activation can also pass the new consensus rule, the old rule can be removed and all chains will use the new rule starting from the genesis block. + +## Backward compatibility + +The new rule is striker than the old one thus it can be deployed via a soft fork. When most nodes have upgraded to the new version, the old versions can keep up to date although blocks generated by old versions may be rejected by new version nodes. From 3bdb8c39ae1285eb057a8e13f384bbd37e99d592 Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 2 Mar 2022 11:53:40 +0800 Subject: [PATCH 2/4] Apply suggestions from code review --- .../0030-ensure-index-less-than-length-in-since.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md b/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md index ce4940a72..63560f106 100644 --- a/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md +++ b/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md @@ -72,7 +72,7 @@ using rational number operations. ## Test Vectors -When `since` uses the absolute epoch `99 + 360 / 180`, and the current epoch is `100 + 0 / 180`, the transaction is mature using the old consensus rule but is immature using the new rule. +When `since` uses the absolute epoch `99 + 360 / 180`, and the current epoch is `100 + 0 / 180`, the transaction is mature using the old consensus rule but is invalid using the new rule. ## Deployment From f57402586a3cc70d13cfa21a1533a4fd2d08bd6e Mon Sep 17 00:00:00 2001 From: ian Date: Mon, 14 Mar 2022 16:22:56 +0800 Subject: [PATCH 3/4] revise rfc30 according to the review comment --- ...-ensure-index-less-than-length-in-since.md | 72 ++++++------------- 1 file changed, 23 insertions(+), 49 deletions(-) diff --git a/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md b/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md index 63560f106..5d7f9fc02 100644 --- a/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md +++ b/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md @@ -11,64 +11,38 @@ Created: 2021-02-04 ## Abstract -This document proposes to fix a bug in the CKB reference implementation. When a transaction input uses the epoch with fraction in the `since` field, the `value` must ensure that the index is less than the length. +This document proposes adding a new consensus rule to verify the `since` field in the transaction. -## Motivation - -The `value` part is an encoded number `epoch + index / length`. In CKB, every block is also assigned an epoch number with a fraction. If the block is the `I`th block in the epoch which epoch number is `E` and length is `L`, its epoch number with the fraction is `E + I / L` and `I` must be less than `L`. - -To verify that a transaction is mature since an absolute epoch number with a fraction, the current implementation assumes that `index` must be less than `length` and checks that: - -``` -E > epoch -or (E == epoch and I / L >= index/length) -``` +As described in the RFC17, [Transaction valid since](../0017-tx-valid-since/0017-tx-valid-since.md), when a transaction input uses the epoch with fraction in the `since` field, the `value` is an encoded rational number `E + I / L`, where -This is not consistent when using relative flag in the `since` field, where the `value` is considered as a rational number and added to the cell start epoch. - -This document suggests adding a new rule to verify that when `since` uses epoch as the unit, it must ensure that index is less than the length. - -See RFC17 [Transaction valid since](../0017-tx-valid-since/0017-tx-valid-since.md) for details of the `since` field encoding patterns. - -## Specification +- `E` is the epoch number. +- `I` is the block index in the epoch. +- `L` is the epoch length. -### Since Absolute Epoch +This RFC requires that when any transaction uses the epoch with fraction as the unit, the encoded number `E + I / L` is valid only if -When an input `since` field is present, and +- `I` is less than `L`, or +- `I` and `L` are both zero. -* The `metric_flag` is epoch (01). -* The `relative_flag` is absolute (0). +If any `since` field is invalid, the transaction is rejected. -Providing that `value` is the encoded number `epoch + index / length`, the transaction is valid only if `index` is less than `length` or both `index` and `length` are zero \*. - -> \* When both `index` and `length` are zero, `value` is converted to `epoch + 0 / 1`. - -If the current epoch number with the fraction is `E + I / L`, the transaction is considered mature when - -``` -E + I / L >= epoch + index / length -``` - -using rational number operations. - -### Since Relative Epoch +## Motivation -When an input `since` field is present, and +The `since` field prevents the transaction from being mined before an absolute or relative time. -* The `metric_flag` is epoch (01). -* The `relative_flag` is relative (1). +When the `since` field uses epoch with fraction number as the unit, the `value` is an encoded rational number `E + I / L`. If it is a relative time, the rational number is used as it is. But when it is the absolute time, the special rule, **Absolute Epoch With Fraction Value Normalization** as mentioned in RFC17, requires normalizing the number to `E + 1 + 0 / 1` when `I` equals to or is larger than `L`. +This document suggests adding a new rule to verify that when `since` uses epoch as the unit, it must ensure that the index `I` is less than the length `L`. -Providing that `value` is the encoded number `epoch + index / length`, the transaction is valid only if `index` is less than `length` or both `index` and `length` are zero \*. +## Specification -> \* When both `index` and `length` are zero, `value` is converted to `epoch + 0 / 1`. +This RFC adds a new verification requirement on the transaction `since` field. -If the cell creation epoch number with fraction is `e + i / l`, and the current epoch number with the fraction is `E + I / L`, the transaction is considered mature when +When an input `since` field is present, and the `metric_flag` is epoch (01), the `value` part is the encoded number `E + I / L`. No matter whether the relative flag is `relative` or `absolute`, the number is valid if and only if -``` -E + I / L >= e + i / l + epoch + index / length -``` +- `I` is less than `L`, or +- `I` and `L` are both zero. -using rational number operations. +There are no changes to the rules in RFC17, except that **Absolute Epoch With Fraction Value Normalization** is no longer needed. ## Test Vectors @@ -76,12 +50,12 @@ When `since` uses the absolute epoch `99 + 360 / 180`, and the current epoch is ## Deployment -The deployment can be performed in two stages. +The deployment can advance in two stages. -The first stage will activate the new consensus rule starting from a specific epoch. The mainnet and testnet will use different starting epochs and all other chains will use the new rule from epoch 0. +The first stage will activate the new consensus rule, starting from a specific epoch. The mainnet and testnet will use different starting epochs and all other chains will use the new rule from epoch 0. -The second stage is optional. After the new rule has been activated, and the blocks in the chain before activation can also pass the new consensus rule, the old rule can be removed and all chains will use the new rule starting from the genesis block. +The second stage is optional. After the new rule is active, and the blocks in the chain before activation can also pass the new consensus rule, the old rule is redundant and can be safely removed. ## Backward compatibility -The new rule is striker than the old one thus it can be deployed via a soft fork. When most nodes have upgraded to the new version, the old versions can keep up to date although blocks generated by old versions may be rejected by new version nodes. +The new rule is striker than the old one, thus it can be deployed via a soft fork. When most nodes have upgraded to the new version, the old versions can keep up to date, although new version nodes may reject blocks generated by old versions. From 8aca73fbef063dedb7e58109f68c7b35326d027f Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 16 Mar 2022 07:39:40 +0800 Subject: [PATCH 4/4] Update rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md Co-authored-by: busyforking <5958+janx@users.noreply.github.com> --- .../0030-ensure-index-less-than-length-in-since.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md b/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md index 5d7f9fc02..db44552cd 100644 --- a/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md +++ b/rfcs/0030-ensure-index-less-than-length-in-since/0030-ensure-index-less-than-length-in-since.md @@ -58,4 +58,4 @@ The second stage is optional. After the new rule is active, and the blocks in th ## Backward compatibility -The new rule is striker than the old one, thus it can be deployed via a soft fork. When most nodes have upgraded to the new version, the old versions can keep up to date, although new version nodes may reject blocks generated by old versions. +The new rule is stricter than the old one thus it can be deployed via a soft fork. When most mining nodes have upgraded to the new version, the old version full nodes can keep up to date. Blocks generated by old version mining nodes may be rejected by new version full nodes.