Segmentation

Currently, we have witnesses and approvers for the Wine subjects. However, a problem arises with one of the nodes we added, SFO, as it is specific to Spain, and we do not want it to influence decisions made in other countries.

To address this need, the concept of segmentation by namespace emerges. This allows us to define specific permissions and roles for certain namespaces, ensuring that only nodes we consider valid can access specific information based on our interests.

With this new knowledge, it is time to continue adapting our use case. PremiumWines not only has vineyards in Spain but also in France, allowing them to produce bottles with different origins. As we know, in Spain, there is an organization (SFO) capable of approving the quality analysis of the product, but this is not the case in France, where this responsibility falls on WFO.

To achieve what we propose, we need to make some changes to the current schema:

  • PremiumWines should be able to create subjects in both countries, so it must be a creator in the “Spain” and “France” namespaces.
  • WFO becomes a witness and approver for wines in both Spain and France.
  • External invocations should be allowed in both Spain and France.
  • SFO will only be an approver and witness for Spanish wines.

First, let’s check the roles of the governance before making these changes:

We will make changes to the roles declared in the governance. Here’s how the properties should look after the modifications:

To generate these changes, we will use our tool kore-Patch following this procedure:

kore-patch '{"roles":[{"namespace":"","role":"WITNESS","schema":{"ID":"governance"},"who":"MEMBERS"},{"namespace":"","role":"APPROVER","schema":{"ID":"governance"},"who":{"NAME":"WPO"}},{"namespace":"","role":"CREATOR","schema":{"ID":"Wine"},"who":{"NAME":"PremiumWines"}},{"namespace":"","role":"APPROVER","schema":{"ID":"governance"},"who":{"NAME":"WFO"}},{"namespace":"","role":"VALIDATOR","schema":{"ID":"governance"},"who":{"NAME":"WFO"}},{"namespace":"","role":"EVALUATOR","schema":{"ID":"governance"},"who":{"NAME":"WFO"}},{"namespace":"","role":"WITNESS","schema":{"ID":"Wine"},"who":{"NAME":"WFO"}},{"namespace":"","role":"ISSUER","schema":{"ID":"Wine"},"who":"NOT_MEMBERS"},{"namespace":"","role":"WITNESS","schema":{"ID":"Wine"},"who":{"NAME":"SFO"}},{"namespace":"","role":"APPROVER","schema":{"ID":"Wine"},"who":{"NAME":"SFO"}}]}' '{"roles":[{"namespace":"","role":"WITNESS","schema":{"ID":"governance"},"who":"MEMBERS"},{"namespace":"","role":"APPROVER","schema":{"ID":"governance"},"who":{"NAME":"WPO"}},{"namespace":"Spain","role":"CREATOR","schema":{"ID":"Wine"},"who":{"NAME":"PremiumWines"}},{"namespace":"France","role":"CREATOR","schema":{"ID":"Wine"},"who":{"NAME":"PremiumWines"}},{"namespace":"","role":"APPROVER","schema":{"ID":"governance"},"who":{"NAME":"WFO"}},{"namespace":"","role":"VALIDATOR","schema":{"ID":"governance"},"who":{"NAME":"WFO"}},{"namespace":"","role":"EVALUATOR","schema":{"ID":"governance"},"who":{"NAME":"WFO"}},{"namespace":"Spain","role":"WITNESS","schema":{"ID":"Wine"},"who":{"NAME":"WFO"}},{"namespace":"France","role":"WITNESS","schema":{"ID":"Wine"},"who":{"NAME":"WFO"}},{"namespace":"Spain","role":"APPROVER","schema":{"ID":"Wine"},"who":{"NAME":"WFO"}},{"namespace":"France","role":"APPROVER","schema":{"ID":"Wine"},"who":{"NAME":"WFO"}},{"namespace":"Spain","role":"ISSUER","schema":{"ID":"Wine"},"who":"NOT_MEMBERS"},{"namespace":"France","role":"ISSUER","schema":{"ID":"Wine"},"who":"NOT_MEMBERS"},{"namespace":"Spain","role":"WITNESS","schema":{"ID":"Wine"},"who":{"NAME":"SFO"}},{"namespace":"Spain","role":"APPROVER","schema":{"ID":"Wine"},"who":{"NAME":"SFO"}}]}'

The result obtained will be:

Next, we will invoke the governance contract method responsible for updating its properties:

After sending the governance update request, we will receive an approval notification. To do this, run the following command:

curl --request GET 'http://localhost:3000/approval-requests?status=Pending'

Copy the value of the id field from the notification and request approval from WPO and WFO:

curl --request PATCH 'http://localhost:3000/approval-requests/{{PREVIUS-ID}}' \
--header 'Content-Type: application/json' \
--data-raw '{"state": "RespondedAccepted"}'
curl --request PATCH 'http://localhost:3002/approval-requests/{{PREVIUS-ID}}' \
--header 'Content-Type: application/json' \
--data-raw '{"state": "RespondedAccepted"}'

If everything went well, when you execute the following command, the governance sn should be 7, and the changes made earlier should be displayed:

curl --request GET 'http://localhost:3000/subjects?subject_type=governances'

Once we have implemented namespace segmentation, we will perform tests to verify its correct functioning.

Let’s create a French wine bottle using the following command:

curl --request POST 'http://localhost:3001/event-requests' \
--header 'Content-Type: application/json' \
--data-raw '{
    "request": {
        "Create": {
        "governance_id": "{{GOVERNANCE-ID}}",
        "schema_id": "Wine",
        "namespace": "France",
        "name": "Wine"
        }
    }
}'

When you perform this action, you will receive a request-id, which you should copy and use in the following command:

curl --request GET 'http://localhost:3001/event-requests/{{REQUEST-ID}}/state'

This last command will give you a response similar to the following:

{
    "id": "{{REQUEST-ID}}",
    "subject_id": "{{SUBJECT-ID}}",
    "sn": 0,
    "state": "finished",
    "success": true
}

To check our new wine bottle, execute the following command:

curl --request GET 'http://localhost:3001/subjects/{{SUBJECT-ID}}'
{
    "subject_id": "{{SUBJECT-ID}}",
    "governance_id": "{{GOVERNANCE-ID}}",
    "sn": 0,
    "public_key": "E5DkRaljajwUZ1HrpgdkIxdTu0fbrg-nqoBJFHqm6GJY",
    "namespace": "France",
    "name": "Wine",
    "schema_id": "Wine",
    "owner": "{{CONTROLLER-ID}}",
    "creator": "{{CONTROLLER-ID}}",
    "properties": {
        "grape": null,
        "harvest": 0,
        "organic_certified": null,
        "origin": "",
        "temperature_control": {
            "last_check": 0,
            "temperature_ok": true
        }
    },
    "active": true
}

But if we execute:

curl --request GET 'http://localhost:3000/subjects/{{SUBJECT-ID}}'

We get 404 arror because of the segmentation we have applied changing the namespace, which determine who are the witnesses of the subject.

Initialize the bottle before testing the certification event issuance:

curl --request POST 'http://localhost:3001/event-requests' \
--header 'Content-Type: application/json' \
--data-raw '{
    "request": {
        "Fact": {
            "subject_id": {{SUBJECT-ID}},
            "payload": {
                "Init": {
                    "harvest": 2,
                    "grape": "Chardonnay",
                    "origin": "france"
                }
            }
        }
    }
}'

Now, when you execute the subject query again, it should have a sn value of 1 and display the previously mentioned information:

curl --request GET 'http://localhost:3001/subjects/{{SUBJECT-ID}}'
{
    "subject_id": "{{SUBJECT-ID}}",
    "governance_id": "{{GOVERNANCE-ID}}",
    "sn": 1,
    "public_key": "E5DkRaljajwUZ1HrpgdkIxdTu0fbrg-nqoBJFHqm6GJY",
    "namespace": "France",
    "name": "Wine",
    "schema_id": "Wine",
    "owner": "{{CONTROLLER-ID}}",
    "creator": "{{CONTROLLER-ID}}",
    "properties": {
        "grape": "Chardonnay",
        "harvest": 2,
        "organic_certified": null,
        "origin": "france",
        "temperature_control": {
            "last_check": 0,
            "temperature_ok": true
        }
    },
    "active": true
}

We will test issuing the certification event. To do this, we will generate the event signature we want to issue using kore-Sign, with the following format, replacing subject_id with the identifier of our wine subject:

kore-sign 'f855c6736463a65f515afe7b85d1418c096ed73852b42bbe4c332eb43d532326' '{"Fact":{"subject_id":"{{SUBJECT-ID}}","payload":{"OrganicCertification":{"fertilizers_control":false,"pesticides_control":false,"analytics":false,"additional_info":"test"}}}}'

The result of this execution will be included in the following request:

curl --request POST 'http://localhost:3001/event-requests' \
--header 'Content-Type: application/json' \
--data-raw {{SIGN-RESULT}}

This will give us a result similar to the following:

curl --request POST 'http://localhost:3001/event-requests' \
--header 'Content-Type: application/json' \
--data-raw '{
    "request": {
        "Fact": {
        "subject_id": {{SUBJECT-ID}},
        "payload": {
            "OrganicCertification": {
            "additional_info": "test",
            "analytics": false,
            "fertilizers_control": false,
            "pesticides_control": false
            }
        }
        }
    },
    "signature": {
        "signer": "EzzmRjc8CtjzHu3MKmuTgnmOTgrJlYZj1D2DCZ9nN7Vk",
        "timestamp": 1689858060412988735,
        "value": "SEiF6C6zhFxzxs56nY6vk4ySTl7zvpV2gExTiiGlbxKI-HVvizL6eYmjV9IjE8GJMzOIQkok8rUehRVK9cNgSfCg"
    }
}'

If the segmentation has been successfully applied, the approval message for this subject should only have been received by WFO. To check it, execute the following command:

curl --request GET 'http://localhost:3002/approval-requests?status=pending'

Copy its id and use it to accept it with the following request:

curl --request PATCH 'http://localhost:3002/approval-requests/{{PREVIUS-ID}}' \
--header 'Content-Type: application/json' \
--data-raw '{"state": "RespondedAccepted"}'

Now, when you query the subject again, it should show a sn value of 2, and the organic_certified field should be false:

curl --request GET 'http://localhost:3001/subjects?subject_type=all&governanceid={{GOVERNANCE-ID}}'
{
    "subject_id": "{{SUBJECT_ID}}",
    "governance_id": "{{GOVERNANCE-ID}}",
    "sn": 2,
    "public_key": "E5DkRaljajwUZ1HrpgdkIxdTu0fbrg-nqoBJFHqm6GJY",
    "namespace": "France",
    "name": "Wine",
    "schema_id": "Wine",
    "owner": "{{CONTROLLER-ID}}",
    "creator": "{{CONTROLLER-ID}}",
    "properties": {
        "grape": "Chardonnay",
        "harvest": 2,
        "organic_certified": false,
        "origin": "france",
        "temperature_control": {
            "last_check": 0,
            "temperature_ok": true
        }
    },
    "active": true
}
Last modified: June 6, 2024