diff --git a/RFC_PROXY_AGENT.md b/RFC_PROXY_AGENT.md new file mode 100644 index 0000000..ac5118e --- /dev/null +++ b/RFC_PROXY_AGENT.md @@ -0,0 +1,304 @@ +# Public Cluster Verification Problems + +## Original Problems + +In the original design of the Spore Protocol, the creation of a Spore with a Cluster ID required the following conditions: + +1. The referenced Cluster Cell must be found in the `CellDeps`. +2. The referenced Cluster Cell must be found in the `Inputs`. +3. The referenced Cluster Cell must be found in the `Outputs`. + +This verification process ensures ownership of the referenced Cluster Cell, preventing malicious activities on one's private Cluster. + +While this design prevents minting in a private Cluster when ownership is absent, challenges remain in public Clusters. In public mining, ownership is nullified upon a customized lock (e.g., [anyone-can-pay](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0026-anyone-can-pay/0026-anyone-can-pay.md)) is introduced. However, this gives rise to the issue of cell competition: if two minting transactions are accidentally sent simultaneously, one will be rejected. The target Cluster gets consumed and recreated by one transaction, requiring reconstruction of the rejected transaction to proceed with minting. + +## Solution + +At this stage, the **owner** needs to create a special cell, here we called it **Cluster Proxy Cell** + +A Cluster Proxy Cell’s structure is like below: + +```yaml +Cluster Proxy Cell: + Data: REFERENCED_CLUSTER_ID + Type: + code_hash: CLUSTER_PROXY_TYPE_HASH + args: [] + Lock: + +``` + +The Type args can be: + +- args: +- args: + +Where `cluster_proxy_id = hash(Inputs[0], Output_Index)` + +### Step1: Creating Cluster Proxy Cell + +Creating a Cluster Proxy Cell can be done in two ways. The first method is putting a Cluster Cell to Inputs & Outputs, as shown below: + +#### Method 1. Use Direct Input + +```yaml +CellDeps: + + + Cluster Cell A: + Data: <...> + Type: + args: CLUSTER_ID_A + code_hash: CLUSTER_TYPE_HASH_A + Lock: +Inputs: + Cluster Cell A: + Type: + args: CLUSTER_ID_A + code_hash: CLUSTER_TYPE_HASH_A + Lock: + <...any other cells> +Outputs: + Cluster Cell A: + Type: + args: CLUSTER_ID_A + code_hash: CLUSTER_TYPE_HASH_A + Lock: + Cluster Proxy Cell: + Data: CLUSTER_ID_A + Type: + code_hash: CLUSTER_PROXY_TYPE_HASH + args: CLUSTER_PROXY_ID_A + Lock: + # for example, acp +``` + +The other method is using an Input Cell with same Lock to the Cluster Cell to create a Cluster Proxy Cell. + +#### Method 2. Use Lock Proxy + +```yaml +CellDeps: + + Cluster Cell A: + Type: + args: CLUSTER_ID_A + code_hash: CLUSTER_TYPE_HASH_A + Lock: + args: + code_hash: LOCK_CODE_HASH_A +Inputs: + Any Cell: + Lock: + args: + code_hash: LOCK_CODE_HASH_A + <...any other cells> +Outputs: + Cluster Proxy Cell: + Data: CLUSTER_ID_A + Type: + code_hash: CLUSTER_PROXY_TYPE_HASH + args: CLUSTER_PROXY_ID + Lock: + # for example, acp + <...any other cells> +``` + +### Step2: Create Cluster Agent Cell + +Once the Cluster owner created the Cluster Proxy Cell, anyone who is able to unlock the Cluster Proxy Cell is able to create a special type cell called: Cluster Agent Cell. Holder of this Cluster Agent Cell can mint Spore in a regular process and put it into the referenced Cluster. + +```yaml +Cluster Agent Cell: + Data: Type Hash of Referenced Cluster Proxy + Type: + code_hash: CLUSTER_AGENT_TYPE_HASH + args: REFERENCED_CLUSTER_ID + Lock: + +``` + +There are two ways to create a Cluster Proxy Agent Cell. + +#### Method 1. Direct Input + +```yaml +CellDeps: + + + Cluster Proxy Cell: + Data: CLUSTER_ID_A + Type: + code_hash: CLUSTER_PROXY_TYPE_HASH + args: CLUSTER_PROXY_ID + Lock: + +Inputs: + Cluster Proxy Cell: + Data: CLUSTER_ID_A + Type: + code_hash: CLUSTER_PROXY_TYPE_HASH + args: CLUSTER_PROXY_ID + Lock: + + <...any other cells> +Outputs: + Cluster Agent Cell: + Data: Hash(ClusterProxyCell.Type) + Type: + code_hash: CLUSTER_AGENT_TYPE_HASH + args: CLUSTER_ID_A + Lock: + + + Cluster Proxy Cell: + Data: CLUSTER_ID_A + Type: + code_hash: CLUSTER_PROXY_TYPE_HASH + args: CLUSTER_PROXY_ID + Lock: + + <...any other cells> +``` + +# Method 2. Use Payment Appearance + +Alternatively, you can make a payment to the Cluster Proxy owner to create a Cluster Agent Cell. This method essentially involves transferring capacity to the same lock address with the Cluster Proxy. + +```yaml +CellDeps: + + Cluster Proxy Cell: + Data: CLUSTER_ID_A + Type: + code_hash: CLUSTER_PROXY_TYPE_HASH + args: + Lock: + code_hash: CODE_HASH_A + args: PUBKEY_A +Inputs: + Payment Cell: # + Capacity: N # N >= MINIMAY_PAYMENT_A + Lock: + <...any other cells> +Outputs: + Cluster Agent Cell: + Data: Hash(ClusterProxyCell.Type) + Type: + code_hash: CLUSTER_AGENT_TYPE_HASH + args: CLUSTER_ID_A + Lock: + + + Receivement Cell: + Capacity: N + Lock: + code_hash: CODE_HASH_A + args: PUBKEY_A + <...any other cells> +``` + +Here, the payment cell serves merely as an example; it can be any unlockable cell and is not limited to only one cell. + +### Step3: Mint Spore with Cluster Agent + +The Cluster Agent Cell holder can mint Spore using three valid methods listed below. + +#### Method 1. Mint With Direct Input + +```yaml +CellDeps: + +Inputs: + Cluster Agent Cell A: + Type: + args: CLUSTER_ID_A + code_hash: CLUSTER_AGENT_TYPE_HASH + Lock: + <...any other cells> +Outputs: + Spore Cell: + Capacity: N CKBytes + Data: + content-type: "image/png" + content: BYTES_OF_THE_IMAGE + cluster: CLUSTER_ID_A + Type: + hash_type: "data1" + code_hash: SPORE_TYPE_DATA_HASH # hash of Spore's type script data hash + args: SPORE_ID + Lock: + + Cluster Agent Cell A: + Data: Hash(ClusterProxyCell.Type) + Type: + code_hash: CLUSTER_AGENT_TYPE_HASH + args: CLUSTER_ID_A + Lock: + # for example, acp +``` + +#### Method 2. Mint With Lock Proxy + +```yaml +CellDeps: + + Cluster Agent Cell A: + Data: Hash(Cluster_Proxy_Cell_Type) + Type: + args: CLUSTER_ID_A + code_hash: CLUSTER_AGENT_TYPE_HASH + Lock: + args: + code_hash: LOCK_CODE_HASH_A +Inputs: + Any Cell: # Lock Proxy Cell + Lock: + args: + code_hash: LOCK_CODE_HASH_A + <...any other cells> +Outputs: + Spore Cell: + Capacity: N CKBytes + Data: + content-type: "image/png" + content: BYTES_OF_THE_IMAGE + cluster: CLUSTER_ID_A + Type: + hash_type: "data1" + code_hash: SPORE_TYPE_DATA_HASH # hash of Spore's type script data hash + args: SPORE_ID + Lock: + +``` + +#### Method 3. Mint With Signature (Not Implemented) + +```yaml +CellDeps: + + Cluster Agent Cell A: + Type: + args: CLUSTER_ID_A + code_hash: CLUSTER_AGENT_TYPE_HASH + Lock: + args: + code_hash: LOCK_CODE_HASH_A +Inputs: + <...any other cells> +Outputs: + Spore Cell: + Capacity: N CKBytes + Data: + content-type: "image/png" + content: BYTES_OF_THE_IMAGE + cluster: CLUSTER_ID_A + Type: + hash_type: "data1" + code_hash: SPORE_V1_DATA_HASH # hash of Spore's type script data hash + args: SPORE_ID + Lock: + +Witnesses: + +```