From 0829f9031ae55a525a6abfd60ffd732bd1efb0a0 Mon Sep 17 00:00:00 2001 From: Sergio Demian Lerner <1752347+SergioDemianLerner@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:37:56 -0300 Subject: [PATCH 1/9] Peg-out acceptance, initial commit --- IPs/RSKIPx.md | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 IPs/RSKIPx.md diff --git a/IPs/RSKIPx.md b/IPs/RSKIPx.md new file mode 100644 index 00000000..e3132088 --- /dev/null +++ b/IPs/RSKIPx.md @@ -0,0 +1,102 @@ +--- +rskip: +title: Peg-out Acceptance +description: +status: Draft +purpose: Usa +author: SDL (@sergiodemianlerner) +layer: Core +complexity: 2 +created: 2022-09-06 +--- +# Peg-out Acceptance + +|RSKIP | | +| :------------ |:-------------| +|**Title** |Peg-out Acceptance| +|**Created** |06-SEP-2022 | +|**Author** |SDL | +|**Purpose** |Usa | +|**Layer** |Core | +|**Complexity** |2 | +|**Status** |Draft | +|**discussions-to** || + +# **Abstract** + +This RSKIP proposes enables pegnatories to accept specific peg-outs from a peg-out batch, and reject the rest. + +# **Motivation** + +The bridge contract is not designed to allow the blocking of peg-outs. Pegnatories may be requested to do it. To comply, pegnatories may need to turn off the PowHSM devices. However, the peg-outs are executed as soon as the devices are turned on and connected to the network again. The bridge assumes peg-out transactions are aways executed and it cannot cancel a peg-out already commanded. Peg-outs are grouped in batches so that a Bitcoin transaction can contain several peg-outs and therefore selective blocking cannot be performed. + +In this proposal, we give pegnatories the capability to accept peg-outs before they are included in the batch and signed. + +# **Specification** + +When the method `releaseBtc()` is called, the peg-out request is stored temporarily in a new map named `pendingApprovals`. The key in the map is the RSK transaction hash where the peg-out request originated. The data in the map consist of: + +* The peg-out request data +* The list of pegnatories that have already approved this peg-out request, as a bit-vector. +* The current number of approvals +* The block number where this peg-out request was issued. + +Two new methods are created for the bridge contract: + +* `uint32 approve(bytes32 RSKtxHash)` +* `uint32 cancel(bytes32 RSKtxHash)` + +While the peg-out request is in the `pendingApprovals` map, pegnatories can call the method `approve(RSKtxHash)`. When the RSKtxHash exists in the map, and the pegnatory signature is valid and it is the first time the pegnatory approves the peg-out request, and the threshold has not been reached: + +1. The number of approvals for this peg-out request is incremented by one +2. The pegnatory index is added to its approvals bit-vector. +3. The block height is stored. + +In this case the `approve` method then returns 1. +If the pegnatory signature is invalid (not a member of the powpeg), then the method does nothing and returns 2. +If a valid pegnatory calls this method more than once, the following calls are ignored, and the method returns 3. +When the signatories threshold of approvals is reached, the request is moved to the peg-out queue, and the method returns 4. + +If a user calls `cancel(RSKtxHash)` and the peg-out RSKtxHash request exists, and the current block height is higher than the block number stored in the map plus 3000, the peg-out request is removed from the `pendingApprovals` map, and the amount locked for peg-out is returned to the same EOA it came from, using direct account balance modification. In this case, the returned value is 1. If the peg-out request does not exist, the returned value is 2. If the block heght deadline has not been reached, the returned value is 3. + +The Gas cost of each method call is 23000, irrespective of the return value. + +## Internal Storage + +Entries in the `pendingApprovals` are stored as independent cells in the Bridge contract storage. To derive the storage address, the message `("pendingApproval-" + Hex(RSKtxHash))` is hashed with Keccak256. The function Hex() returns the 64-byte lowercase hexadecimal representation of the hash without the "0x" prefix. + +The peg-out request payload consist of: + +* `destination` +* `amount` +* `rskTxHash` +* `blockNumber` +* `approvalCount` +* `approvals` + +The `approvalCount` is stored as an `int16`. +The `approvals` field is a bit-vector of fixed size 32 bytes (supports a maximum of 256 pegnatories). +The `blockNumber` is stored as an `int32`. + + +# Rationale + +TBD. + +# Backwards Compatibility + +This change is a hard-fork and therefore all full nodes must be updated. + + +# Test Cases + +TBD + +## Security Considerations + +No security risks have been identified related to this change. + + +# **Copyright** + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 7e93483588c206a7d57ad0428b5792737d87d9dd Mon Sep 17 00:00:00 2001 From: Sergio Demian Lerner <1752347+SergioDemianLerner@users.noreply.github.com> Date: Tue, 6 Sep 2022 22:57:27 -0300 Subject: [PATCH 2/9] Numbered. Gas costs improved --- IPs/RSKIP350.md | 103 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 IPs/RSKIP350.md diff --git a/IPs/RSKIP350.md b/IPs/RSKIP350.md new file mode 100644 index 00000000..c6116df0 --- /dev/null +++ b/IPs/RSKIP350.md @@ -0,0 +1,103 @@ +--- +rskip: 350 +title: Peg-out Acceptance +description: +status: Draft +purpose: Usa +author: SDL (@sergiodemianlerner) +layer: Core +complexity: 2 +created: 2022-09-06 +--- +# Peg-out Acceptance + +|RSKIP | 350 | +| :------------ |:-------------| +|**Title** |Peg-out Acceptance| +|**Created** |06-SEP-2022 | +|**Author** |SDL | +|**Purpose** |Usa | +|**Layer** |Core | +|**Complexity** |2 | +|**Status** |Draft | +|**discussions-to** || + +# **Abstract** + +This RSKIP proposes enables pegnatories to accept specific peg-outs from a peg-out batch, and reject the rest. + +# **Motivation** + +The bridge contract is not designed to allow the blocking of peg-outs. Pegnatories may be requested to do it. To comply, pegnatories may need to turn off the PowHSM devices. However, the peg-outs are executed as soon as the devices are turned on and connected to the network again. The bridge assumes peg-out transactions are aways executed and it cannot cancel a peg-out already commanded. Peg-outs are grouped in batches so that a Bitcoin transaction can contain several peg-outs and therefore selective blocking cannot be performed. + +In this proposal, we give pegnatories the capability to accept peg-outs before they are included in the batch and signed. + +# **Specification** + +When the method `releaseBtc()` is called, the peg-out request is stored temporarily in a new map named `pendingApprovals`. The key in the map is the RSK transaction hash where the peg-out request originated. The data in the map consist of: + +* The peg-out request data +* The list of pegnatories that have already approved this peg-out request, as a bit-vector. +* The current number of approvals +* The block number where this peg-out request was issued. + +Two new methods are created for the bridge contract: + +* `uint32 approve(bytes32 RSKtxHash)` +* `uint32 cancel(bytes32 RSKtxHash)` + +Both methods can be called by EOAs or by the `CALL` opcodes. +While the peg-out request is in the `pendingApprovals` map, pegnatories can call the method `approve(RSKtxHash)`. When the RSKtxHash exists in the map, and the msg.sender is a valid pegnatory and it is the first time the pegnatory approves the peg-out request, and the threshold has not been reached: + +1. The number of approvals for this peg-out request is incremented by one +2. The pegnatory index is added to its approvals bit-vector. +3. The block height is stored. + +In this case the `approve` method then returns 1. +If the msg.sender is not a valid pegnatory, then the method does nothing and returns 2. +If a valid pegnatory calls this method more than once, the following calls are ignored, and the method returns 3. +When the signatories threshold of approvals is reached, the request is moved to the peg-out queue, and the method returns 4. + +If a user calls `cancel(RSKtxHash)` and the peg-out RSKtxHash request exists, and the current block height is higher than the block number stored in the map plus 3000, the peg-out request is removed from the `pendingApprovals` map, and the amount locked for peg-out is returned to the same EOA it came from, using direct account balance modification. In this case, the returned value is 1. If the peg-out request does not exist, the returned value is 2. If the block heght deadline has not been reached, the returned value is 3. + +The gas cost of the `approve` method is set to 5000, irrespective of the return value. The cost of `cancel` is set to 5000. The cost of `releaseBtc()` is increased to 50000, to account for up to 7 approvals. + +## Internal Storage + +Entries in the `pendingApprovals` are stored as independent cells in the Bridge contract storage. To derive the storage address, the message `("pendingApproval-" + Hex(RSKtxHash))` is hashed with Keccak256. The function Hex() returns the 64-byte lowercase hexadecimal representation of the hash without the "0x" prefix. + +The peg-out request payload consist of: + +* `destination` +* `amount` +* `rskTxHash` +* `blockNumber` +* `approvalCount` +* `approvals` + +The `approvalCount` is stored as an `int16`. +The `approvals` field is a bit-vector of fixed size 32 bytes (supports a maximum of 256 pegnatories). +The `blockNumber` is stored as an `int32`. + + +# Rationale + +TBD. + +# Backwards Compatibility + +This change is a hard-fork and therefore all full nodes must be updated. + + +# Test Cases + +TBD + +## Security Considerations + +No security risks have been identified related to this change. + + +# **Copyright** + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 0868d5dcbef0b32bc826201c40a3ca2fc4f2b1bc Mon Sep 17 00:00:00 2001 From: Sergio Demian Lerner <1752347+SergioDemianLerner@users.noreply.github.com> Date: Tue, 6 Sep 2022 22:58:43 -0300 Subject: [PATCH 3/9] deleted old file --- IPs/RSKIPx.md | 102 -------------------------------------------------- 1 file changed, 102 deletions(-) delete mode 100644 IPs/RSKIPx.md diff --git a/IPs/RSKIPx.md b/IPs/RSKIPx.md deleted file mode 100644 index e3132088..00000000 --- a/IPs/RSKIPx.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -rskip: -title: Peg-out Acceptance -description: -status: Draft -purpose: Usa -author: SDL (@sergiodemianlerner) -layer: Core -complexity: 2 -created: 2022-09-06 ---- -# Peg-out Acceptance - -|RSKIP | | -| :------------ |:-------------| -|**Title** |Peg-out Acceptance| -|**Created** |06-SEP-2022 | -|**Author** |SDL | -|**Purpose** |Usa | -|**Layer** |Core | -|**Complexity** |2 | -|**Status** |Draft | -|**discussions-to** || - -# **Abstract** - -This RSKIP proposes enables pegnatories to accept specific peg-outs from a peg-out batch, and reject the rest. - -# **Motivation** - -The bridge contract is not designed to allow the blocking of peg-outs. Pegnatories may be requested to do it. To comply, pegnatories may need to turn off the PowHSM devices. However, the peg-outs are executed as soon as the devices are turned on and connected to the network again. The bridge assumes peg-out transactions are aways executed and it cannot cancel a peg-out already commanded. Peg-outs are grouped in batches so that a Bitcoin transaction can contain several peg-outs and therefore selective blocking cannot be performed. - -In this proposal, we give pegnatories the capability to accept peg-outs before they are included in the batch and signed. - -# **Specification** - -When the method `releaseBtc()` is called, the peg-out request is stored temporarily in a new map named `pendingApprovals`. The key in the map is the RSK transaction hash where the peg-out request originated. The data in the map consist of: - -* The peg-out request data -* The list of pegnatories that have already approved this peg-out request, as a bit-vector. -* The current number of approvals -* The block number where this peg-out request was issued. - -Two new methods are created for the bridge contract: - -* `uint32 approve(bytes32 RSKtxHash)` -* `uint32 cancel(bytes32 RSKtxHash)` - -While the peg-out request is in the `pendingApprovals` map, pegnatories can call the method `approve(RSKtxHash)`. When the RSKtxHash exists in the map, and the pegnatory signature is valid and it is the first time the pegnatory approves the peg-out request, and the threshold has not been reached: - -1. The number of approvals for this peg-out request is incremented by one -2. The pegnatory index is added to its approvals bit-vector. -3. The block height is stored. - -In this case the `approve` method then returns 1. -If the pegnatory signature is invalid (not a member of the powpeg), then the method does nothing and returns 2. -If a valid pegnatory calls this method more than once, the following calls are ignored, and the method returns 3. -When the signatories threshold of approvals is reached, the request is moved to the peg-out queue, and the method returns 4. - -If a user calls `cancel(RSKtxHash)` and the peg-out RSKtxHash request exists, and the current block height is higher than the block number stored in the map plus 3000, the peg-out request is removed from the `pendingApprovals` map, and the amount locked for peg-out is returned to the same EOA it came from, using direct account balance modification. In this case, the returned value is 1. If the peg-out request does not exist, the returned value is 2. If the block heght deadline has not been reached, the returned value is 3. - -The Gas cost of each method call is 23000, irrespective of the return value. - -## Internal Storage - -Entries in the `pendingApprovals` are stored as independent cells in the Bridge contract storage. To derive the storage address, the message `("pendingApproval-" + Hex(RSKtxHash))` is hashed with Keccak256. The function Hex() returns the 64-byte lowercase hexadecimal representation of the hash without the "0x" prefix. - -The peg-out request payload consist of: - -* `destination` -* `amount` -* `rskTxHash` -* `blockNumber` -* `approvalCount` -* `approvals` - -The `approvalCount` is stored as an `int16`. -The `approvals` field is a bit-vector of fixed size 32 bytes (supports a maximum of 256 pegnatories). -The `blockNumber` is stored as an `int32`. - - -# Rationale - -TBD. - -# Backwards Compatibility - -This change is a hard-fork and therefore all full nodes must be updated. - - -# Test Cases - -TBD - -## Security Considerations - -No security risks have been identified related to this change. - - -# **Copyright** - -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 805ee4700cd4f018dc0b6d01656e7c96adc462ab Mon Sep 17 00:00:00 2001 From: Sergio Demian Lerner <1752347+SergioDemianLerner@users.noreply.github.com> Date: Tue, 6 Sep 2022 23:00:25 -0300 Subject: [PATCH 4/9] typo --- IPs/RSKIP350.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IPs/RSKIP350.md b/IPs/RSKIP350.md index c6116df0..dcd2dc22 100644 --- a/IPs/RSKIP350.md +++ b/IPs/RSKIP350.md @@ -28,7 +28,7 @@ This RSKIP proposes enables pegnatories to accept specific peg-outs from a peg-o # **Motivation** -The bridge contract is not designed to allow the blocking of peg-outs. Pegnatories may be requested to do it. To comply, pegnatories may need to turn off the PowHSM devices. However, the peg-outs are executed as soon as the devices are turned on and connected to the network again. The bridge assumes peg-out transactions are aways executed and it cannot cancel a peg-out already commanded. Peg-outs are grouped in batches so that a Bitcoin transaction can contain several peg-outs and therefore selective blocking cannot be performed. +The bridge contract is not designed to allow the blocking of peg-outs. Pegnatories may be requested to do it. To comply, pegnatories may need to turn off the PowHSM devices. However, the peg-outs are executed as soon as the devices are turned on and connected to the network again. The bridge assumes peg-out transactions are always executed and it cannot cancel a peg-out already commanded. Peg-outs are grouped in batches so that a Bitcoin transaction can contain several peg-outs and therefore selective blocking cannot be performed. In this proposal, we give pegnatories the capability to accept peg-outs before they are included in the batch and signed. From 444656cd3689153f1c5d39d29b2a68eb277c2b5b Mon Sep 17 00:00:00 2001 From: Sergio Demian Lerner <1752347+SergioDemianLerner@users.noreply.github.com> Date: Wed, 7 Sep 2022 10:10:29 -0300 Subject: [PATCH 5/9] version with approveUpto --- IPs/RSKIP350.md | 102 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 27 deletions(-) diff --git a/IPs/RSKIP350.md b/IPs/RSKIP350.md index dcd2dc22..b21d1530 100644 --- a/IPs/RSKIP350.md +++ b/IPs/RSKIP350.md @@ -24,65 +24,113 @@ created: 2022-09-06 # **Abstract** -This RSKIP proposes enables pegnatories to accept specific peg-outs from a peg-out batch, and reject the rest. +This RSKIP proposes enables pegnatories to accept specific peg-outs from a peg-out batch, and reject specific peg-outs, or accept/reject all outstanding peg-outs. # **Motivation** -The bridge contract is not designed to allow the blocking of peg-outs. Pegnatories may be requested to do it. To comply, pegnatories may need to turn off the PowHSM devices. However, the peg-outs are executed as soon as the devices are turned on and connected to the network again. The bridge assumes peg-out transactions are always executed and it cannot cancel a peg-out already commanded. Peg-outs are grouped in batches so that a Bitcoin transaction can contain several peg-outs and therefore selective blocking cannot be performed. +The bridge contract is not designed to allow the blocking of peg-outs. Pegnatories may be requested to do it. To comply, pegnatories may need to turn off the PowHSM devices. However, the peg-outs are executed as soon as the devices are turned on and connected to the network again. The bridge assumes peg-out transactions are always executed and it cannot cancel a peg-out already commanded. Peg-outs are grouped in batches so that a Bitcoin transaction can contain several peg-outs and therefore selective blocking cannot be performed. In this proposal, we give pegnatories the capability to accept peg-outs before they are included in the batch and signed. # **Specification** -When the method `releaseBtc()` is called, the peg-out request is stored temporarily in a new map named `pendingApprovals`. The key in the map is the RSK transaction hash where the peg-out request originated. The data in the map consist of: +When the method `releaseBtc()` is called, the peg-out request is stored temporarily in a new map named `pendingPegoutRequests`. The requests are identified by Keccak(`rskTxHash`,`parentBlockId`) where `parentBlockId ` represent the id of the parent block. -* The peg-out request data -* The list of pegnatories that have already approved this peg-out request, as a bit-vector. -* The current number of approvals -* The block number where this peg-out request was issued. +key in the map is the hash of RSK transaction hash where the peg-out request originated. The data in the map consist of: + +* The peg-out request data (`senderAddress`, `amount`, `rskTxHash`) +* `voted`: The list of pegnatories that have already acceptd or rejected this peg-out request, as a bit-vector. +* `acceptanceCount`: the current number of acceptances +* `rejectionCount`: the current number of rejections +* `blockNumber`: the block number where this peg-out request was issued. +* `previous`: the id of the previous peg-out request, or zero if none. +* `next`: the id of the next peg-out request, or zero if none. + +This forms a linked list of pending requests. + +Note that the entry does not stores the Bitcoin destination address, but the RSK sender address, to enable reimbursements. -Two new methods are created for the bridge contract: +Initially, the fields `acceptanceCount`, `rejectionCount` and `voted` are set to zero and the block height is stored in `blockNumber`. + +Five new methods are created for the bridge contract: + +* `accept(bytes32 requestId) returns (uint32)` +* `reject(bytes32 requestId) returns (uint32)` +* `cancel(bytes32 requestId) returns (uint32)` +* `acceptUpto(bytes32 requestId,uint32 maxEntries)` +* `rejectUpto(bytes32 requestId,uint32 maxEntries)` -* `uint32 approve(bytes32 RSKtxHash)` -* `uint32 cancel(bytes32 RSKtxHash)` +All methods can be called by EOAs or by the `CALL` opcodes. +The cost of `releaseBtc()` is increased to 50000, to account for up to 7 rejections. -Both methods can be called by EOAs or by the `CALL` opcodes. -While the peg-out request is in the `pendingApprovals` map, pegnatories can call the method `approve(RSKtxHash)`. When the RSKtxHash exists in the map, and the msg.sender is a valid pegnatory and it is the first time the pegnatory approves the peg-out request, and the threshold has not been reached: -1. The number of approvals for this peg-out request is incremented by one -2. The pegnatory index is added to its approvals bit-vector. -3. The block height is stored. +## accept +While the peg-out request is in the `pendingPegoutRequests` map, pegnatories can call the method `accept(requestId)`. When the requestId exists in the map, and the msg.sender is a valid pegnatory and it is the first time the pegnatory accepts or rejects the peg-out request, and the reject or accept thresholds have not been reached: -In this case the `approve` method then returns 1. +1. The number of acceptances for this peg-out request (`acceptanceCount`) is incremented by one +2. The pegnatory index is added to its `voted` bit-vector. + +In this case the `accept` method then returns 1. If the msg.sender is not a valid pegnatory, then the method does nothing and returns 2. If a valid pegnatory calls this method more than once, the following calls are ignored, and the method returns 3. -When the signatories threshold of approvals is reached, the request is moved to the peg-out queue, and the method returns 4. +When the signatories threshold of acceptances is reached, the request is moved to the peg-out queue, un-linked from the embedded link-list, and the method returns 4. When moving to the request to the release request queue, the Bitcoin destination address should be computed from the stored `senderAddress`. +The gas cost of the `accept` method is set to 5000. + +## reject +While the peg-out request is in the `pendingPegoutRequests` map, pegnatories can call the method `reject(requestId)`. When the requestId exists in the map, and the msg.sender is a valid pegnatory and it is the first time the pegnatory accepts or rejects the peg-out request, and the reject or accept thresholds have not been reached: -If a user calls `cancel(RSKtxHash)` and the peg-out RSKtxHash request exists, and the current block height is higher than the block number stored in the map plus 3000, the peg-out request is removed from the `pendingApprovals` map, and the amount locked for peg-out is returned to the same EOA it came from, using direct account balance modification. In this case, the returned value is 1. If the peg-out request does not exist, the returned value is 2. If the block heght deadline has not been reached, the returned value is 3. +1. The number of rejections for this peg-out (`rejectionCount`) request is incremented by one +2. The pegnatory index is added to its acceptances bit-vector. -The gas cost of the `approve` method is set to 5000, irrespective of the return value. The cost of `cancel` is set to 5000. The cost of `releaseBtc()` is increased to 50000, to account for up to 7 approvals. + +In this case the `reject` method then returns 1. +If the msg.sender is not a valid pegnatory, then the method does nothing and returns 2. +If a valid pegnatory calls this method more than once, the following calls are ignored, and the method returns 3. +When the signatories threshold of rejections is reached, the request is cancelled and the method returns 4. The rejection threshold is the number of pegnatories minus the acceptance threshold, plus one. + +The gas cost of the `reject` method is set to 5000. + +## cancel +If a user calls `cancel(requestId)` and the peg-out requestId request exists, and the current block height is higher than the block number stored in the map plus 3000, the peg-out request is removed from the `pendingPegoutRequests` map, and it is unlinked from the linked-lisst. This involves eventually modifying the previous and next request records of point at each other. The amount locked in the peg-out request removed is returned to the `senderAddress`, using direct account balance modification. In this case, the returned value is 1. If the peg-out request does not exist, the returned value is 2. If the block heght deadline has not been reached, the returned value is 3. + +The gas cost of `cancel` is set to 15000. +## acceptUpto + +This method enables the acceptance of all pending peg-out requests up to a certain pending request, and upto a maximum number of pending requests scanned given as argument. +The method does not return any value. +The gas cost of the `acceptUpto` method is set to 5000*maxEntries. + +## rejectUpto + +This method enables the rejection of all pending peg-out requests up to a certain pending request, and upto a maximum number of pending requests scanned given as argument. +The method does not return any value. +The gas cost of the `rejectUpto` method is set to 5000*maxEntries. ## Internal Storage -Entries in the `pendingApprovals` are stored as independent cells in the Bridge contract storage. To derive the storage address, the message `("pendingApproval-" + Hex(RSKtxHash))` is hashed with Keccak256. The function Hex() returns the 64-byte lowercase hexadecimal representation of the hash without the "0x" prefix. +Entries in the `pendingPegoutRequests` are stored as independent cells in the Bridge contract storage. To derive the storage address, the message `("pendingacceptance-" + Hex(requestId))` is hashed with Keccak256. The function Hex() returns the 64-byte lowercase hexadecimal representation of the hash without the "0x" prefix. The peg-out request payload consist of: -* `destination` +* `senderAddress` * `amount` * `rskTxHash` * `blockNumber` -* `approvalCount` -* `approvals` - -The `approvalCount` is stored as an `int16`. -The `approvals` field is a bit-vector of fixed size 32 bytes (supports a maximum of 256 pegnatories). +* `acceptanceCount` +* `rejectionCount` +* `voted` +* `previous` +* `next` + +The `acceptanceCount` and `rejectionCount` fields are stored as an `int16`. +The `voted ` field is a bit-vector of fixed size 16 bytes (supports a maximum of 128 pegnatories). The `blockNumber` is stored as an `int32`. +The `previous` and `next` fields are stored as `uint256`. # Rationale -TBD. +The flexibility to accept/reject all or specific peg-outs reduces the number of Bridge calls required and hashes transferred. # Backwards Compatibility From 03aeae56258962dc5cb72f0031f4bd022bf55999 Mon Sep 17 00:00:00 2001 From: Sergio Demian Lerner <1752347+SergioDemianLerner@users.noreply.github.com> Date: Wed, 7 Sep 2022 10:27:53 -0300 Subject: [PATCH 6/9] Nice, but does not work because mutable data. --- IPs/RSKIP350.md | 51 ++++++++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/IPs/RSKIP350.md b/IPs/RSKIP350.md index b21d1530..5b56cc73 100644 --- a/IPs/RSKIP350.md +++ b/IPs/RSKIP350.md @@ -52,59 +52,54 @@ Note that the entry does not stores the Bitcoin destination address, but the RSK Initially, the fields `acceptanceCount`, `rejectionCount` and `voted` are set to zero and the block height is stored in `blockNumber`. -Five new methods are created for the bridge contract: +These new methods are created for the bridge contract: -* `accept(bytes32 requestId) returns (uint32)` -* `reject(bytes32 requestId) returns (uint32)` -* `cancel(bytes32 requestId) returns (uint32)` -* `acceptUpto(bytes32 requestId,uint32 maxEntries)` -* `rejectUpto(bytes32 requestId,uint32 maxEntries)` +* `getPendingPegoutState(bytes32 requestId) returns (bytes)` +* `cancelPendingPegout(bytes32 requestId) returns (uint32)` +* `acceptPendingPegouts(bytes32 requestId,uint32 maxEntries)` +* `rejectPendingPegouts(bytes32 requestId,uint32 maxEntries)` All methods can be called by EOAs or by the `CALL` opcodes. The cost of `releaseBtc()` is increased to 50000, to account for up to 7 rejections. +To help us define these external methods, we first define 2 internal methods `accept(requestId)` and `reject(requestId)`. ## accept -While the peg-out request is in the `pendingPegoutRequests` map, pegnatories can call the method `accept(requestId)`. When the requestId exists in the map, and the msg.sender is a valid pegnatory and it is the first time the pegnatory accepts or rejects the peg-out request, and the reject or accept thresholds have not been reached: +When the `requestId` exists in the map, and the msg.sender is a valid pegnatory and the pegnatory index is not set in `voted`, and the reject or accept thresholds have not been reached: 1. The number of acceptances for this peg-out request (`acceptanceCount`) is incremented by one -2. The pegnatory index is added to its `voted` bit-vector. +2. The pegnatory index is set in its `voted` bit-vector. -In this case the `accept` method then returns 1. -If the msg.sender is not a valid pegnatory, then the method does nothing and returns 2. -If a valid pegnatory calls this method more than once, the following calls are ignored, and the method returns 3. -When the signatories threshold of acceptances is reached, the request is moved to the peg-out queue, un-linked from the embedded link-list, and the method returns 4. When moving to the request to the release request queue, the Bitcoin destination address should be computed from the stored `senderAddress`. -The gas cost of the `accept` method is set to 5000. +When the signatories threshold of acceptances is reached, the request is moved to the peg-out queue, un-linked from the embedded link-list, and an event `pegOutAccepted(requestId, rskTxHash)` is emitted. When moving to the request to the release request queue, the Bitcoin destination address should be computed from the stored `senderAddress`. ## reject -While the peg-out request is in the `pendingPegoutRequests` map, pegnatories can call the method `reject(requestId)`. When the requestId exists in the map, and the msg.sender is a valid pegnatory and it is the first time the pegnatory accepts or rejects the peg-out request, and the reject or accept thresholds have not been reached: +When the `requestId` exists in the map, and the msg.sender is a valid pegnatory and the pegnatory index is not set in `voted`, and the reject or accept thresholds have not been reached: 1. The number of rejections for this peg-out (`rejectionCount`) request is incremented by one -2. The pegnatory index is added to its acceptances bit-vector. +2. The pegnatory index is set in its `voted` bit-vector. +When the signatories threshold of rejections is reached, the request is cancelled (in a similar way to the cancel method). The rejection threshold is the number of pegnatories minus the acceptance threshold, plus one. -In this case the `reject` method then returns 1. -If the msg.sender is not a valid pegnatory, then the method does nothing and returns 2. -If a valid pegnatory calls this method more than once, the following calls are ignored, and the method returns 3. -When the signatories threshold of rejections is reached, the request is cancelled and the method returns 4. The rejection threshold is the number of pegnatories minus the acceptance threshold, plus one. - -The gas cost of the `reject` method is set to 5000. ## cancel -If a user calls `cancel(requestId)` and the peg-out requestId request exists, and the current block height is higher than the block number stored in the map plus 3000, the peg-out request is removed from the `pendingPegoutRequests` map, and it is unlinked from the linked-lisst. This involves eventually modifying the previous and next request records of point at each other. The amount locked in the peg-out request removed is returned to the `senderAddress`, using direct account balance modification. In this case, the returned value is 1. If the peg-out request does not exist, the returned value is 2. If the block heght deadline has not been reached, the returned value is 3. +If a user calls `cancel(requestId)` and the peg-out requestId request exists, and the current block height is higher than the block number stored in the map plus 3000, the peg-out request is removed from the `pendingPegoutRequests` map, and it is unlinked from the linked-list. This involves eventually modifying the previous and next request records of point at each other. +Also, an event `pegOutCancelled(requestId, rskTxHash)` is emitted. +The amount locked in the peg-out request removed is returned to the `senderAddress`, using direct account balance modification. In this case, the returned value is 1. If the peg-out request does not exist, the returned value is 2. If the block heght deadline has not been reached, the returned value is 3. The gas cost of `cancel` is set to 15000. -## acceptUpto -This method enables the acceptance of all pending peg-out requests up to a certain pending request, and upto a maximum number of pending requests scanned given as argument. +## acceptPendingPegouts + +This method enables the acceptance of all pending peg-out requests up to a certain pending request, and upto a maximum number of pending requests scanned given as argument. The internal `accept` method is called for each of the scanned entries. The method does not return any value. -The gas cost of the `acceptUpto` method is set to 5000*maxEntries. +The gas cost of the `acceptPendingPegouts` method is set to 5000*maxEntries. + +## rejectPendingPegouts -## rejectUpto +This method enables the rejection of all pending peg-out requests up to a certain pending request, and upto a maximum number of pending requests scanned given as argument. The internal `reject` method is called for each of the scanned entries. -This method enables the rejection of all pending peg-out requests up to a certain pending request, and upto a maximum number of pending requests scanned given as argument. The method does not return any value. -The gas cost of the `rejectUpto` method is set to 5000*maxEntries. +The gas cost of the `rejectPendingPegouts` method is set to 5000*maxEntries. ## Internal Storage From 4cc8314c1fc45d0ac3c76aa0e66d9480b3143462 Mon Sep 17 00:00:00 2001 From: Sergio Demian Lerner <1752347+SergioDemianLerner@users.noreply.github.com> Date: Wed, 7 Sep 2022 15:35:35 -0300 Subject: [PATCH 7/9] New proposal avoids mutable maps --- IPs/RSKIP350.md | 121 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 87 insertions(+), 34 deletions(-) diff --git a/IPs/RSKIP350.md b/IPs/RSKIP350.md index 5b56cc73..b0c5d0de 100644 --- a/IPs/RSKIP350.md +++ b/IPs/RSKIP350.md @@ -34,98 +34,151 @@ In this proposal, we give pegnatories the capability to accept peg-outs before t # **Specification** -When the method `releaseBtc()` is called, the peg-out request is stored temporarily in a new map named `pendingPegoutRequests`. The requests are identified by Keccak(`rskTxHash`,`parentBlockId`) where `parentBlockId ` represent the id of the parent block. +`epochLength` is defined as 120 blocks. -key in the map is the hash of RSK transaction hash where the peg-out request originated. The data in the map consist of: +These new methods are created for the bridge contract: + +* `getOpenPegoutEpoch() returns (uint32)` +* `getLastPegoutRequestId() returns (uint256)` +* `getPendingPegoutState(bytes32 requestId) returns (bytes)` +* `acceptPendingPegouts(bytes32 requestId,uint32 maxEntries)` +* `rejectPendingPegouts(bytes32 requestId,uint32 maxEntries)` + +All methods can be called by EOAs or by the `CALL` opcodes. + +Two storage variables are created: + +* `lastRequestId` +* `openEpoch` + +Both are missing (zero) at the begining. +The methods `getOpenPegoutEpoch()` and `getLastPegoutRequestId()` return the values contained in the respective storage fields (`openEpoch` and `lastRequestId`). + +## Changes to releaseBtc + +First, when the method `releaseBtc()` is called, the internal method `epochEndCheck` is called. +Second, if `openEpoch` is lower or equal to the block height divisible by `epochLength`, then its value is replaced by the new epoch value. + +Afterwards, the peg-out request is stored temporarily in a new map named `pendingPegoutRequests`. The map is kept active for `epochLength`. + +Each peg out request is identified its by Keccak(`rskTxHash`,`lastRequestId`) where `lastRequestId` represents the id of the last request. It will be zero (32 zero bytes) if it is the first request in the map. The field `rskTxHash` is the transaction where this peg-out originated. + +The cost of `releaseBtc()` is increased to 50000, to account for up to 7 rejections. On success, the `releaseBtc()` will emit an event `pendingPegout(requestId,rskTxHash)`. + +The `lastRequestId` field is updated with the `requestId` of the request inserted in the map. + +Each entry in the map consist of: * The peg-out request data (`senderAddress`, `amount`, `rskTxHash`) * `voted`: The list of pegnatories that have already acceptd or rejected this peg-out request, as a bit-vector. * `acceptanceCount`: the current number of acceptances * `rejectionCount`: the current number of rejections -* `blockNumber`: the block number where this peg-out request was issued. -* `previous`: the id of the previous peg-out request, or zero if none. -* `next`: the id of the next peg-out request, or zero if none. +* `previous`: the `requestId` of the previous peg-out request in the linked-list, or zero if none. +* `requestEpoch`: the epoch number when this peg-out request was added to the map for the first time. -This forms a linked list of pending requests. +This forms a single-linked list of pending requests. Note that the entry does not stores the Bitcoin destination address, but the RSK sender address, to enable reimbursements. -Initially, the fields `acceptanceCount`, `rejectionCount` and `voted` are set to zero and the block height is stored in `blockNumber`. - -These new methods are created for the bridge contract: - -* `getPendingPegoutState(bytes32 requestId) returns (bytes)` -* `cancelPendingPegout(bytes32 requestId) returns (uint32)` -* `acceptPendingPegouts(bytes32 requestId,uint32 maxEntries)` -* `rejectPendingPegouts(bytes32 requestId,uint32 maxEntries)` +Initially, the fields `acceptanceCount`, `rejectionCount` and `voted` are set to zero. The field `previous` is set to the previous `requestId`. The field `requestEpoch` is filled with the current epoch number (block heigh divided by `epochLength`). -All methods can be called by EOAs or by the `CALL` opcodes. -The cost of `releaseBtc()` is increased to 50000, to account for up to 7 rejections. +To help us define the external methods, we first define 3 internal methods `accept(requestId)` and `reject(requestId)`, `cancel(requestId)`. -To help us define these external methods, we first define 2 internal methods `accept(requestId)` and `reject(requestId)`. ## accept -When the `requestId` exists in the map, and the msg.sender is a valid pegnatory and the pegnatory index is not set in `voted`, and the reject or accept thresholds have not been reached: +When the `requestId` exists in the map, and the `msg.sender` is a valid pegnatory and the pegnatory index is not set in `voted`, and the reject or accept thresholds have not been reached: 1. The number of acceptances for this peg-out request (`acceptanceCount`) is incremented by one 2. The pegnatory index is set in its `voted` bit-vector. -When the signatories threshold of acceptances is reached, the request is moved to the peg-out queue, un-linked from the embedded link-list, and an event `pegOutAccepted(requestId, rskTxHash)` is emitted. When moving to the request to the release request queue, the Bitcoin destination address should be computed from the stored `senderAddress`. - ## reject -When the `requestId` exists in the map, and the msg.sender is a valid pegnatory and the pegnatory index is not set in `voted`, and the reject or accept thresholds have not been reached: +When the `requestId` exists in the map, and the `msg.sender` is a valid pegnatory and the pegnatory index is not set in `voted`, and the reject or accept thresholds have not been reached: 1. The number of rejections for this peg-out (`rejectionCount`) request is incremented by one 2. The pegnatory index is set in its `voted` bit-vector. -When the signatories threshold of rejections is reached, the request is cancelled (in a similar way to the cancel method). The rejection threshold is the number of pegnatories minus the acceptance threshold, plus one. - ## cancel -If a user calls `cancel(requestId)` and the peg-out requestId request exists, and the current block height is higher than the block number stored in the map plus 3000, the peg-out request is removed from the `pendingPegoutRequests` map, and it is unlinked from the linked-list. This involves eventually modifying the previous and next request records of point at each other. -Also, an event `pegOutCancelled(requestId, rskTxHash)` is emitted. -The amount locked in the peg-out request removed is returned to the `senderAddress`, using direct account balance modification. In this case, the returned value is 1. If the peg-out request does not exist, the returned value is 2. If the block heght deadline has not been reached, the returned value is 3. +If the peg-out `requestId` request exists: + +* the storace cells used are zeroed so they are removed from storage +* an event `pegOutCancelled(requestId, rskTxHash)` is emitted +* the amount locked in the peg-out request removed is returned to the `senderAddress`, using direct account balance modification. -The gas cost of `cancel` is set to 15000. +## epochEndCheck + +If the current block number divided by `epochLength` is lower or equal to `openEpoch`, then this method returns immediately. +Otherwise, all elements in the map are scanned using the linked list starting from `lastRequestId`. If for a peg-out request the signatories threshold of acceptance is reached, the request is moved to the peg-out queue, and an event `pegOutAccepted(requestId, rskTxHash)` is emitted. When moving to the request to the release request queue, the Bitcoin destination address should be computed from the stored `senderAddress`. + +All requests that have not reached the peg-out threshold, but their `requestEpoch` curresponds to the previous epoch are moved to a new linked list that will replace the current one (this is done by updating the `previous` fields). Entries are moved presserving their order. The remaining entries are cancelled with `cancel`. +The `lastRequestId` field is set to 32 zero bytes if no request was moved from the previous epoch, or it will contain the `requestId` of the last moved entry. +This method is called by `updateCollections`, `releaseBtc`, `acceptPendingPegouts` and `rejectPendingPegouts`. ## acceptPendingPegouts +First, the `epochEndCheck` method is called. + This method enables the acceptance of all pending peg-out requests up to a certain pending request, and upto a maximum number of pending requests scanned given as argument. The internal `accept` method is called for each of the scanned entries. The method does not return any value. The gas cost of the `acceptPendingPegouts` method is set to 5000*maxEntries. ## rejectPendingPegouts +First, the `epochEndCheck` method is called. + This method enables the rejection of all pending peg-out requests up to a certain pending request, and upto a maximum number of pending requests scanned given as argument. The internal `reject` method is called for each of the scanned entries. The method does not return any value. The gas cost of the `rejectPendingPegouts` method is set to 5000*maxEntries. +## getPendingPegoutState + +This method returns the peg-out request entry serialized. If the `requestId` does not exists, the returned data is empty. + ## Internal Storage -Entries in the `pendingPegoutRequests` are stored as independent cells in the Bridge contract storage. To derive the storage address, the message `("pendingacceptance-" + Hex(requestId))` is hashed with Keccak256. The function Hex() returns the 64-byte lowercase hexadecimal representation of the hash without the "0x" prefix. +Entries in the `pendingPegoutRequests` are stored as independent cells in the Bridge contract storage. To derive the storage address, the message `("pendingAcceptance-" + Hex(requestId))` is hashed with Keccak256. The function Hex() returns the 64-byte lowercase hexadecimal representation of the hash without the "0x" prefix. The peg-out request payload consist of: * `senderAddress` * `amount` * `rskTxHash` -* `blockNumber` * `acceptanceCount` * `rejectionCount` * `voted` * `previous` -* `next` +* `requestEpoch` The `acceptanceCount` and `rejectionCount` fields are stored as an `int16`. -The `voted ` field is a bit-vector of fixed size 16 bytes (supports a maximum of 128 pegnatories). -The `blockNumber` is stored as an `int32`. -The `previous` and `next` fields are stored as `uint256`. +The `voted ` field is a bit-vector of fixed size 16 bytes (supports a maximum of 128 pegnatories). The most significant bit of the first byte corresponds to the first pegnatory. +The `previous` is an `uint256`. All fields are fixed-length. + +## Migration +During powpeg migration, when the new federation is activated, if there are peg-out request outstanding in the map then: + +* All entries have their fields `acceptanceCount`, `rejectionCount` and `voted` zeroed. The fields are zeroed even if they had already reached their acceptance or rejection thresholds. +* The event `pendingPegouts(lastRequestId)` is emmitted. + +The new powpeg must approve or reject the prexisting set of peg-out requests. + +## Peg-out Batching +The batch creation time is redefined in terms of epochs, specifically 3 epochs. Every 3 epochs the bridge will attempt to create a new batch. + +## Peg-out Fee Estimation + +Peg-out fees will be estimated according to the number of transactions queued in the batch, as it is today, and not conting the transactions that are still in the `pendingPegoutRequests` map. # Rationale -The flexibility to accept/reject all or specific peg-outs reduces the number of Bridge calls required and hashes transferred. +This proposal is deisgned to enable batch accepts and rejections, because forcing individual votes can be very costly to pegnatories in terms of gas spent. To enalbe batch votes, it is important that the batch voted cannot change between the time the pegnatory is notified of the batch and the time the vote transaction is included in the blockchain. That's why votes apply to all peg-out requests until a specified point in the batch. An alternative would be to divide the time in two phases, one that builds a batch, and another one for voting. I nthe voting phase, new peg-outs are queued for the following batch. However, this design still has the problem that blockchain reorganizations can change the content of batches, and pegnatories votes should never mutate with block reorganizations. Therefore the votes must include either the id of a chain of peg-outs, or a block hash (which indirectly also fixes all previous peg-out requests). + +This proposal ensures that pegnatories will always have at least one full epoch to accept ore reject a certain peg-out request. Peg-out requests issued close to the deadline of the epoch will be moved to the next epoch. The maximum time a peg-out request can be outstanding is two epochs, minus one block. We set `epochLength` to 120, which corresponds approximately to one hour. This gives enough time for pegnatories to perform any automated check, yet it doesn't block user funds for too long. + +Redefiniting the batching time in term of epochs allow to synchronize both and that the batch waiting time is not extended by one epoch. However, if a peg-out request is issued close to the end of the epoch prior a batch creation, the peg.out may not receive enough votes and it will be delayed until the net batch creation event. + +This proposals has theflexibility to accept/reject all or specific peg-outs to reduce the number of Bridge calls required and hashes transferred. # Backwards Compatibility From fae73bc13a071223386bc0cca81435539cb4f866 Mon Sep 17 00:00:00 2001 From: Sergio Demian Lerner <1752347+SergioDemianLerner@users.noreply.github.com> Date: Mon, 12 Sep 2022 21:56:44 -0300 Subject: [PATCH 8/9] Apply suggestions from code review Co-authored-by: Ilan <36084092+ilanolkies@users.noreply.github.com> --- IPs/RSKIP350.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/IPs/RSKIP350.md b/IPs/RSKIP350.md index b0c5d0de..92eecdc1 100644 --- a/IPs/RSKIP350.md +++ b/IPs/RSKIP350.md @@ -28,7 +28,7 @@ This RSKIP proposes enables pegnatories to accept specific peg-outs from a peg-o # **Motivation** -The bridge contract is not designed to allow the blocking of peg-outs. Pegnatories may be requested to do it. To comply, pegnatories may need to turn off the PowHSM devices. However, the peg-outs are executed as soon as the devices are turned on and connected to the network again. The bridge assumes peg-out transactions are always executed and it cannot cancel a peg-out already commanded. Peg-outs are grouped in batches so that a Bitcoin transaction can contain several peg-outs and therefore selective blocking cannot be performed. +The bridge contract is not designed to allow the blocking of peg-outs. Pegnatories may be requested to do it. To comply, pegnatories may need to turn off the PowHSM devices. However, the peg-outs are executed as soon as the devices are turned on and connected to the network again. The bridge assumes peg-out transactions are always executed, a peg-out that is already commanded cannot be cancelled. Peg-outs are grouped in batches so that a Bitcoin transaction can contain several peg-outs and therefore selective blocking cannot be performed. In this proposal, we give pegnatories the capability to accept peg-outs before they are included in the batch and signed. @@ -78,7 +78,7 @@ Each entry in the map consist of: This forms a single-linked list of pending requests. -Note that the entry does not stores the Bitcoin destination address, but the RSK sender address, to enable reimbursements. +Note that the entry does not store the Bitcoin destination address, but the RSK sender address, to enable reimbursements. Initially, the fields `acceptanceCount`, `rejectionCount` and `voted` are set to zero. The field `previous` is set to the previous `requestId`. The field `requestEpoch` is filled with the current epoch number (block heigh divided by `epochLength`). @@ -101,7 +101,7 @@ When the `requestId` exists in the map, and the `msg.sender` is a valid pegnator ## cancel If the peg-out `requestId` request exists: -* the storace cells used are zeroed so they are removed from storage +* the storage cells used are zeroed so they are removed from storage * an event `pegOutCancelled(requestId, rskTxHash)` is emitted * the amount locked in the peg-out request removed is returned to the `senderAddress`, using direct account balance modification. @@ -137,7 +137,7 @@ This method returns the peg-out request entry serialized. If the `requestId` doe ## Internal Storage -Entries in the `pendingPegoutRequests` are stored as independent cells in the Bridge contract storage. To derive the storage address, the message `("pendingAcceptance-" + Hex(requestId))` is hashed with Keccak256. The function Hex() returns the 64-byte lowercase hexadecimal representation of the hash without the "0x" prefix. +Entries in the `pendingPegoutRequests` are stored as independent cells in the Bridge contract storage. To derive the storage address, the message `("pendingAcceptance-" + Hex(requestId))` is hashed with Keccak256. The function `Hex()` returns the 64-byte lowercase hexadecimal representation of the hash without the "0x" prefix. The peg-out request payload consist of: @@ -172,11 +172,11 @@ Peg-out fees will be estimated according to the number of transactions queued in # Rationale -This proposal is deisgned to enable batch accepts and rejections, because forcing individual votes can be very costly to pegnatories in terms of gas spent. To enalbe batch votes, it is important that the batch voted cannot change between the time the pegnatory is notified of the batch and the time the vote transaction is included in the blockchain. That's why votes apply to all peg-out requests until a specified point in the batch. An alternative would be to divide the time in two phases, one that builds a batch, and another one for voting. I nthe voting phase, new peg-outs are queued for the following batch. However, this design still has the problem that blockchain reorganizations can change the content of batches, and pegnatories votes should never mutate with block reorganizations. Therefore the votes must include either the id of a chain of peg-outs, or a block hash (which indirectly also fixes all previous peg-out requests). +This proposal is deisgned to enable batch accepts and rejections, because forcing individual votes can be very costly to pegnatories in terms of gas spent. To enalbe batch votes, it is important that the batch voted cannot change between the time the pegnatory is notified of the batch and the time the vote transaction is included in the blockchain. That's why votes apply to all peg-out requests until a specified point in the batch. An alternative would be to divide the time in two phases, one that builds a batch, and another one for voting. In the voting phase, new peg-outs are queued for the following batch. However, this design still has the problem that blockchain reorganizations can change the content of batches, and pegnatories votes should never mutate with block reorganizations. Therefore the votes must include either the id of a chain of peg-outs, or a block hash (which indirectly also fixes all previous peg-out requests). This proposal ensures that pegnatories will always have at least one full epoch to accept ore reject a certain peg-out request. Peg-out requests issued close to the deadline of the epoch will be moved to the next epoch. The maximum time a peg-out request can be outstanding is two epochs, minus one block. We set `epochLength` to 120, which corresponds approximately to one hour. This gives enough time for pegnatories to perform any automated check, yet it doesn't block user funds for too long. -Redefiniting the batching time in term of epochs allow to synchronize both and that the batch waiting time is not extended by one epoch. However, if a peg-out request is issued close to the end of the epoch prior a batch creation, the peg.out may not receive enough votes and it will be delayed until the net batch creation event. +Redefining the batching time in term of epochs has two benefits: allows to synchronize both values, and prevents extending the batch waiting time by one epoch. However, if a peg-out request is issued close to the end of the epoch prior a batch creation, the peg.out may not receive enough votes and it will be delayed until the next batch creation event. This proposals has theflexibility to accept/reject all or specific peg-outs to reduce the number of Bridge calls required and hashes transferred. From e5ac07b656c1e9269797f8955e23cf4ac3ee114d Mon Sep 17 00:00:00 2001 From: Sergio Demian Lerner <1752347+SergioDemianLerner@users.noreply.github.com> Date: Sat, 8 Oct 2022 19:01:09 -0300 Subject: [PATCH 9/9] Adddress reviewer's comments --- IPs/RSKIP350.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/IPs/RSKIP350.md b/IPs/RSKIP350.md index 92eecdc1..7093a999 100644 --- a/IPs/RSKIP350.md +++ b/IPs/RSKIP350.md @@ -28,7 +28,7 @@ This RSKIP proposes enables pegnatories to accept specific peg-outs from a peg-o # **Motivation** -The bridge contract is not designed to allow the blocking of peg-outs. Pegnatories may be requested to do it. To comply, pegnatories may need to turn off the PowHSM devices. However, the peg-outs are executed as soon as the devices are turned on and connected to the network again. The bridge assumes peg-out transactions are always executed, a peg-out that is already commanded cannot be cancelled. Peg-outs are grouped in batches so that a Bitcoin transaction can contain several peg-outs and therefore selective blocking cannot be performed. +The bridge contract assumes that peg-out transactions, once commanded, are always executed. In the future, it is possible that regulatory authorities may compel pegnatories to block certain pegouts. Peg-outs are grouped in batches, so a Bitcoin transaction can contain several peg-outs and therefore selective blocking cannot be performed. To comply, pegnatories may need to turn off the PowHSM devices. However, the peg-outs are executed as soon as the devices are turned on and connected to the network again. Selective censorship is currently not allowed. In this proposal, we give pegnatories the capability to accept peg-outs before they are included in the batch and signed. @@ -36,7 +36,7 @@ In this proposal, we give pegnatories the capability to accept peg-outs before t `epochLength` is defined as 120 blocks. -These new methods are created for the bridge contract: +These new methods are created in the bridge contract: * `getOpenPegoutEpoch() returns (uint32)` * `getLastPegoutRequestId() returns (uint256)` @@ -172,9 +172,9 @@ Peg-out fees will be estimated according to the number of transactions queued in # Rationale -This proposal is deisgned to enable batch accepts and rejections, because forcing individual votes can be very costly to pegnatories in terms of gas spent. To enalbe batch votes, it is important that the batch voted cannot change between the time the pegnatory is notified of the batch and the time the vote transaction is included in the blockchain. That's why votes apply to all peg-out requests until a specified point in the batch. An alternative would be to divide the time in two phases, one that builds a batch, and another one for voting. In the voting phase, new peg-outs are queued for the following batch. However, this design still has the problem that blockchain reorganizations can change the content of batches, and pegnatories votes should never mutate with block reorganizations. Therefore the votes must include either the id of a chain of peg-outs, or a block hash (which indirectly also fixes all previous peg-out requests). +This proposal is deigned to enable batch accepts and rejections, because forcing individual votes can be very costly to pegnatories in terms of gas spent. To enable batch votes, it is important that the batch voted cannot change between the time the pegnatory is notified of the batch and the time the vote transaction is included in the blockchain. That's why votes apply to all peg-out requests until a specified point in the batch. An alternative would be to divide the time in two phases, one that builds a batch, and another one for voting. In the voting phase, new peg-outs are queued for the following batch. However, this design still has the problem that blockchain reorganizations can change the content of batches, and pegnatories votes should never mutate with block reorganizations. Therefore the votes must include either the id of a chain of peg-outs, or a block hash (which indirectly also fixes all previous peg-out requests). -This proposal ensures that pegnatories will always have at least one full epoch to accept ore reject a certain peg-out request. Peg-out requests issued close to the deadline of the epoch will be moved to the next epoch. The maximum time a peg-out request can be outstanding is two epochs, minus one block. We set `epochLength` to 120, which corresponds approximately to one hour. This gives enough time for pegnatories to perform any automated check, yet it doesn't block user funds for too long. +This proposal ensures that pegnatories will always have at least one full epoch to accept or reject a certain peg-out request. Peg-out requests issued close to the deadline of the epoch will be moved to the next epoch. The maximum time a peg-out request can be outstanding is two epochs, minus one block. We set `epochLength` to 120, which corresponds approximately to one hour. This gives enough time for pegnatories to perform any automated check, yet it doesn't block user funds for too long. Redefining the batching time in term of epochs has two benefits: allows to synchronize both values, and prevents extending the batch waiting time by one epoch. However, if a peg-out request is issued close to the end of the epoch prior a batch creation, the peg.out may not receive enough votes and it will be delayed until the next batch creation event.