Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CIP-0094? | SPO On-chain Polls #496

Merged
merged 8 commits into from
Jun 9, 2023
Merged

CIP-0094? | SPO On-chain Polls #496

merged 8 commits into from
Jun 9, 2023

Conversation

KtorZ
Copy link
Member

@KtorZ KtorZ commented Apr 4, 2023

Abstract

The Cardano Foundation proposes a mechanism for polling Cardano stake pool operators on specific topics. Polls are done on-chain through transaction metadata and authenticated through stake pool credentials (either VRF public key similar to what's described in CIP-0022 or Ed25519 cold key). The goal is to gather opinions on governance matters such as protocol parameter updates. This standard is an inclusive interim solution while the work on a larger governance framework such as CIP-1694 continues.


View rendered version

@KtorZ KtorZ added the Category: Tools Proposals belonging to the 'Tools' category. label Apr 4, 2023
@KtorZ KtorZ self-assigned this Apr 4, 2023
@KtorZ KtorZ force-pushed the cip-spo-polls branch 2 times, most recently from 86b1dd0 to 5baba83 Compare April 4, 2023 11:00
KtorZ added a commit to CardanoSolutions/cardano-node that referenced this pull request Apr 4, 2023
  The Cardano Foundation proposes a mechanism for polling Cardano stake
  pool operators on specific topics. Polls are done on-chain through
  transaction metadata and authenticated through stake pool credentials
  (either VRF public key similar to what's described in
  [CIP-0022](https://cips.cardano.org/cips/cip22) or Ed25519 cold key).

  The goal is to gather opinions on governance matters such as protocol
  parameters updates. This standard is meant to be an inclusive interim
  solution while the work on a larger governance framework such as
  [CIP-1694](cardano-foundation/CIPs#380)
  continues.

  See [proposed CIP](cardano-foundation/CIPs#496) for details.

  ---

  This commits adds three new commands:

  - create-poll:
      For the current governing entities, as a means to create new polls.

  - answer-poll:
      For participants who want to answer a given poll.

  - verify-poll:
      For anyone who seek to verify a poll entry (e.g. explorers)

  The commands are built to fit and play nicely within the cardano-cli.
  The poll and answers structures are based on transaction metadata and
  require to be embedded in an actual transaction. The added commands
  however only works from metadata and raw "GovernancePoll" envelopes.
KtorZ added a commit to CardanoSolutions/cardano-node that referenced this pull request Apr 4, 2023
  The Cardano Foundation proposes a mechanism for polling Cardano stake
  pool operators on specific topics. Polls are done on-chain through
  transaction metadata and authenticated through stake pool credentials
  (either VRF public key similar to what's described in
  [CIP-0022](https://cips.cardano.org/cips/cip22) or Ed25519 cold key).

  The goal is to gather opinions on governance matters such as protocol
  parameters updates. This standard is meant to be an inclusive interim
  solution while the work on a larger governance framework such as
  [CIP-1694](cardano-foundation/CIPs#380)
  continues.

  See [proposed CIP](cardano-foundation/CIPs#496) for details.

  ---

  This commits adds three new commands:

  - create-poll:
      For the current governing entities, as a means to create new polls.

  - answer-poll:
      For participants who want to answer a given poll.

  - verify-poll:
      For anyone who seek to verify a poll entry (e.g. explorers)

  The commands are built to fit and play nicely within the cardano-cli.
  The poll and answers structures are based on transaction metadata and
  require to be embedded in an actual transaction. The added commands
  however only works from metadata and raw "GovernancePoll" envelopes.
CIP-????/README.md Outdated Show resolved Hide resolved
CIP-????/README.md Outdated Show resolved Hide resolved
CIP-????/README.md Outdated Show resolved Hide resolved
CIP-????/README.md Outdated Show resolved Hide resolved
CIP-????/README.md Outdated Show resolved Hide resolved
CIP-????/README.md Outdated Show resolved Hide resolved
@gitmachtl

This comment was marked as outdated.

@gitmachtl
Copy link
Contributor

I am also linking the following discussion:
input-output-hk/cardano-js-sdk#650

@KtorZ KtorZ changed the title Draft SPO on-chain voting proposal CIP-???? | SPO On-chain Poll Apr 5, 2023
@KtorZ KtorZ changed the title CIP-???? | SPO On-chain Poll CIP-???? | SPO On-chain Polls Apr 5, 2023
@KtorZ
Copy link
Member Author

KtorZ commented Apr 5, 2023

@gitmachtl: So only using the VRF secret key once to register a voting key. After that this voting key is referencing the VRF key and so the VRF key does not have to be used anymore until you wanna change the voting key.

Indeed, we've purposely kept it simple here. Mostly because this is meant to be an interim solution so we don't want to set precedence for a more complex process and a new set of credentials that'll be dropped once another on-chain governance framework enters the picture. That is debatable, but it would be relatively easy to have a first registration of an Ed25519 credential and use that onwards.

@gitmachtl: An addition to cardano-cli should only contain the possibility to sign a provided hex/cbor payload via the VRF key, and not producing any other special structure

Certainly not! That is a recipe for disaster. The next thing you get from that is people signing withdrawal requests or other disruptive actions without them knowing. This is why signing standards (e.g. COSE) always come with well-defined structures; We do not want people to sign arbitrary payloads. They always can through low-level libraries but higher-level interfaces such as the "official" cardano cli shall certainly not promote that as a benign command.

@gitmachtl: I would really avoid using the pool cold key for such actions, its the worse key you wanna want to be exposed. Also, it would automatically leave out all SPOs with there pool cold keys on the hw-wallet.

I am also from that school, but I got convinced by some others who actually prefer using their cold key for such an action as they see it as the right tool for the job. Hence the flexibility in the proposal; those who prefer using the VRF can, and those who prefer using their cold key can. I see good arguments for both.

Copy link
Collaborator

@rphair rphair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️ This looks fine to me as both a reviewer and an SPO but will wait until the technical considerations are settled before submitting an endorsing review.

CIP-????/README.md Outdated Show resolved Hide resolved
@perturbing

This comment was marked as resolved.

CIP-????/README.md Outdated Show resolved Hide resolved
@gitmachtl

This comment was marked as resolved.

@KtorZ

This comment was marked as resolved.

@KtorZ KtorZ changed the title CIP-???? | SPO On-chain Polls CIP-0094? | SPO On-chain Polls Apr 18, 2023
dcoutts

This comment was marked as outdated.

@dcoutts

This comment was marked as resolved.

@gitmachtl

This comment was marked as resolved.

@iquerejeta
Copy link
Contributor

I think it's ok to use the VRF key to provide a proof of possession of the VRF skey (which is what we are ultimately doing with the VRF proof). However, I agree with Duncan in that it is not a signature, so the wording should be very explicit and should be chosen carefully, as indeed misuse of the keys would have catastrophic consequences. If registering yet another key is a possibility, I'd prefer that.

I don't like using the cold key for polls because we want to incentivise SPOs to have their cold keys in an air-gapped machine, but we also want to incentives SPOs to participate in polls. If polls happen often, we are not providing the right incentives.

My order of preference of possible solutions would be (1) registering a new ed25510 key, (2) use KES key (which actually is meant to sign data to identify an SPO, (3) VRF key, and finally (4) the cold key. Using some sort of padding in the message, as @perturbing suggested, might be a solution against possible misuse, but does not solve the real problem.

However, I understand that some people might want to have the highest level of identification guarantees for polls, therefore supporting the usage of cold keys.

@gitmachtl

This comment was marked as resolved.

@KtorZ
Copy link
Member Author

KtorZ commented Apr 19, 2023

Thanks all for your feedback; I have addressed them directly in the CIP to make sure that the conversations are captured over time. Here's however a summary of the changes / additions:

  • (cc @dcoutts, @iquerejeta) I have made clearer the distinction between VRF proofs & digital signatures, see for example:

    "A digital signature (EdDSA) from the SPO's current cold key, or a VRF proof proving ownership of associated VRF credentials."

  • (cc @Crypto2099) I have clarified usage of the field 3:

    "The field 3 represents the 0-based index of the chosen answer from the available choices (from field 1 of the target poll)."

  • (cc @perturbing) All examples are now proper "test vectors" (i.e. they correspond to what's generated from cardano-cli).

  • (cc @dcoutts, @perturbing) I've added a proper disclaimer regarding re-use of Ed25519 secret key as VRF secrets:

    Warning

    Note that the VRF here is NOT used as a digital signature algorithm, but used to produce a proof of possession of the corresponding VRF secret key. This is a slight abuse of the VRF scheme since the verifiable random output produced is completely discarded, though safe provided that the VRF secret key was generated independently of the cold key.

    Let's stress this out a little: it is extremely important for implementors to keep that difference in mind and to NOT attempt to use the cold key as a VRF secret in an attempt to generate a VRF proof! Ed25519 is only proven secure in the setting where an adversary has access to only signatures. Attempting to re-use the same secret for different purpose could have dramatic consequences.

    See Insecurity On Secret Key Re-Usage for further detail.

  • (cc @perturbing) I have expanded on the intent of the survey and the interpretation of the data:

    The outcome of a poll will depend on its level of participation (in terms of stake). It is essential to understand that we explicitly call this a poll / survey and not a vote to dispel any possible confusion. So it is akin to 1 Lovelace = 1 Voice although we may chose to interpret data using different equations (e.g. giving more weight to pledged stake). How the data is interpret is deemed out of the scope of this proposal which aims mainly at producing the data-points. Further conversations and debates will be needed regarding interpretation of the data-points.

  • (cc @gitmachtl, @iquerejeta) I have given a justification as for why we do not use the KES scheme here, though left the door open

    There's a third on-chain element which we could use for identifying SPOs which is a digital signature from their KES credentials. It is however a bit more annoying to leverage mainly because KES are meant to expire and are only loosely tied to pools by operational certificate. Thus, verifying KES signatures on a survey requires a more complex setup and monitoring to keep track of operational certificates and their validity at the time of the survey.

    If this CIP was meant to NOT be an interim solution, this is something we would likely consider. However, given the timeframe we're looking at and the overall trade-offs in complexity, we have opted out of using the KES as an authentication mechanism in this iteration.

  • (cc @iquerejeta) I have given a justification as for why we do not use proxy keys here too, though also left the door open

Another possible alternative to what's described in the CIP would be to have SPOs register a proxy Ed25519 key and use that proxy key onward. The validity of the proxy key registration would be conditionned to the production of an associated VRF proof or a digital signature from the cold key (very much like it's done for operational certificate).

Yet, like the KES alternative, this option is in conflict with some of the design goals of this CIP: simplicity. All the more so given that we want to maximise participation of SPOs to the various surveys. We aim to make the process of participating to the survey as simple as possible, without compromising on security.

Note Both alternative options for KES Signing and Proxy Keys may be re-considered in a future version of the survey. Especially if the solution turns out to be not as temporary as intended. Fortunately, the current design decisions do not preclude this from happening as it shall be possible to introduce two new witness types 6 and 7 for those purpose. The KES registration can be handled through a separate on-chain event.

  • (cc @dcoutts) I have given a justification as for why we do not leverage the existing witness structure on transactions

    In the current proposal, we serialize signatures and proofs directly within the transaction metadata. One could make the argument that there's already room for Ed25519 key witness in the transaction which could be re-used here instead of being embedded in metadata. However, this is impractical in two places:

    • For producers of these metadata, which now have two inconsistent flow for producing witness. Indeed, there's no equivalent witness in the transaction for storing VRF proof, so proving using a VRF secret key will have to go in the metadata, whereas a digital signature could go as normal witness. Note that the ledger doesn't allow extraneous witnesses, which means that a signer would also have to add an "extra required signer" to the transaction; generating even more inconsistency.

    • For consumers of these metadata, which instead of relying on one consistent source of data (parsing metadata), now needs to also parse other parts of transactions, making the entire discovery process more involved.

@dmitrystas
Copy link

if an SPO posts an answer that is not in the list of answers (for example the poll contains only 3 options 0,1,2, but SPO posts 5 in the field_3, which logic should be in this case? should we completely ignore this voice, and not take it into account at all (and take into account the SPO voice next time if the SPO sends the correct answer later), or should we take into account this voice as wrong/broken, and not take into account any other posts from this SPO?

@gitmachtl
Copy link
Contributor

gitmachtl commented May 7, 2023

just mark it as "SPO is stupid" 😄

normally i guess it should be marked as invalid. the question is, should this appearance count to be the first one. or should the dashboards/tools only take the first valid one into account?

@KtorZ
Copy link
Member Author

KtorZ commented May 7, 2023

@ashisherc there can be more than just the cold key hash in the required signers indeed. It doesn't invalidate the answers. There must be at least the cold key hash.

@dmitrystas if an SPO submits a well formed but invalid answer then it counts as his/her answer but it doesn't contribute towards one of the existing choice. That means that even if they submit another (valid) answer, it is only the first one that is taken into account.

@dmitrystas
Copy link

dmitrystas commented May 7, 2023

should the dashboards/tools only take the first valid one into account?

@gitmachtl yep, only the 1st one

@gitmachtl
Copy link
Contributor

@dmitrystas so valid is if the metadata is ok, the required signer is ok and the transaction is signed with the proper cold key. even if the answer in the metadata has an invalid value. correct?

@dmitrystas
Copy link

@gitmachtl as far as I understand Matthias' answer - yes, even in case the key 3 has an invalid (not from poll's option list) value. Only the required signers are important, and a well formed metadata with key 2 as poll hash and key 3 with answer. I broke the value for a one pool locally, just for a test to check how it works - it looks something like this https://prnt.sc/0VmWtRJjEFKm

@KtorZ
Copy link
Member Author

KtorZ commented May 7, 2023

Indeed @gitmachtl; this is the distinction I make between well-formed and valid. A well formed submission can have an out-of-bound answer.

I've written a crawler script which captures those validations. I am still on the fence as for whether we should allow multiple submissions in case of a well formed but invalid answer. I don't see any (security) reason to allow multiple submissions in that case and only consider the first well formed but valid answer. But there's also no strong reason to make validations more complicated than necessary... that's more room for mistakes.


### Question structure

A question is posted in a transaction's metadata using the metadata label `94` and the following metadata structure:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this use of label 94 been added to CIP-0010?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet! I originally wanted to validate the approach on cip-0094 before doing that but I guess it's now time. Thanks for the reminder 👌

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should, together with this CIP being set to active state

>
> Only the first answer to a poll for each credential shall be considered. If multiple answers are found, only the first answer submitted (transaction & block ordering tallying) shall be considered.

### Procedure and Duration
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me, what is missing from this specification is an explanation of the full poll flow, for example:

  • how can SPOs can find new polls to vote on?
  • how any ecosystem actor can verify the results of a poll?
  • where does the report get posted?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've addressed those points in separate documents and tutorial by now. Thing is, I don't necessarily want to take a strong stance about these in the CIP itself to not force one single approach.

The data lives on chain as transaction metadata which means that it's just the usual approach for any tool or builder to get access to it. We now even have dashboards in at least two explorers (adastat and cardanoscan) that are collecting and validating these data. And it's relatively straightforward with a chain sync. More tools will likely follow.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment, every question with the label 94 appears on-chain for all to see. Technically, from this moment on, anyone - with a pool s key - can pick up this question and submit an answer. It is up to the publishing entity to set the cast and redelegation duration. But it is not up to this one entity to interpret or publish the result, because it has no right to decide about the interpretation or reaction of the other entities.

Like the question, all individual ballots are transparent and verifiable on-chain. The transaction format with the --required-signer-hash ensures that only ballots validly signed by a pool end up on chain.

To make the on-chain data easily accessible for those who do not have a full indexing instance (e.g. dbsync) available, the CardanoFoundation has set up a github repository where an index file in json format is maintained. There you can find (for now) the cast/delegation epochs in a standardized machine-readable format. In addition, there is also the possibility to store list of all ballots that were considered valid summarized in one file, in order to give everyone easy access and the possibility of their own analysis and interpretation.

The methodology deliberately chosen in this poll design is a creative+inclusive+motivational iteration. This perhaps somewhat contradicts the common expectation that a CIP must be written (first define, then implement, then execute)
In this process, we deliberately wanted to present a maximally simple, straight executable thing, with lots of room for ideas. People should have the opportunity to get hands-on experience during the build process and participate in the rest of the design. At the beginning of the project it was still unclear whether this was only a one-time test run with the goal of incorporating the data and findings into the design of CIP-1694, or whether it would make sense to refine this CIP step by step for further test runs.

CIP-0094/README.md Outdated Show resolved Hide resolved

### Outcome

The outcome of a poll will depend on its level of participation (in **terms of stake**). It is essential to understand that we explicitly call this a _poll_ / _survey_ and not a _vote_ to dispel any possible confusion. So it is akin to `1 Lovelace = 1 Voice` although we may chose to interpret data using different equations (e.g. giving more weight to pledged stake). How the data is interpret is deemed out of the scope of this proposal which aims mainly at producing the data-points. Further conversations and debates will be needed regarding interpretation of the data-points.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we explicitly call this a poll / survey and not a vote

Except in the Procedure and Duration section where its referenced as a vote :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hehe, this is an addition I didn't write and missed the wording. But I'll correct it :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed this

replace vote/ballot by answer
explain the current definition of answer and delegation durations
@rphair
Copy link
Collaborator

rphair commented May 20, 2023

@KtorZ @gufmar This question is long-term for the CIP but also urgent because I'd like to submit the current mainnet poll based on the answer...

The CIP deals with operational details like security, but it's also operationally important for poll responders to add metadata. What's the proper way of doing this? And would it therefore make sense for CIP-0094 to explain how to use it with CIP-0020 transaction messaging, assuming that's possible?

Following the mainnet tutorial (dev portal version, currently more up-to-date) & adding a 674 metadata section to the generated JSON:

{
    "94": {
        "map": [
            {
                "k": {
                    "int": 2
                },
                "v": {
                    "bytes": "96861fe7da8d45ba5db95071ed3889ed1412929f33610636c072a4b5ab550211"
                }
            },
            {
                "k": {
                    "int": 3
                },
                "v": {
                    "int": 5
                }
            }
        ]
    },
    "674":
         {
           "msg":
                  [
"The results of this poll can't be actionable ..."
                  ]
         }
}

doesn't seem compatible with --json-metadata-detailed-schema which I assume is required to map the poll data... perhaps because the CIP-0020 message specification doesn't have a detailed schema:

cardano-cli transaction build-raw \
...
--metadata-json-file votemeta.json \
--json-metadata-detailed-schema \
...
Command failed: transaction build-raw  Error: Error reading metadata at: "votemeta.json"
JSON schema error within the metadata item 674: {"msg":["The results of this poll can't be actionable ...
JSON object does not match the schema.
Expected a single field named "int", "bytes", "string", "list" or "map".
Unexpected object field(s): {"msg":["The results of this poll can't be actionable ...

It would seem an important part of the voting process, especially with the popular "none of the above" category of our current mainnet vote, that explanatory messages with our votes be readable by the growing number of Tx message metadata parsers in pool explorers and wallets. So how can we combine the CIP-0020 messaging and CIP-0094 voting metadata structures in a single transaction?

@dmitrystas
Copy link

dmitrystas commented May 20, 2023

CIP-0020 message specification doesn't have a detailed schema

{
    "674": {
        "map": [
            {
                "k": {
                    "string": "msg"
                },
                "v": {
                    "list": [{
                        "string": "The results of this poll can't be actionable ..."
                    }]
                }
            }
        ]
    }
}

or option 2 - you can use no-schema-formed metadata

{
    "94": {
        "2": "0x96861fe7da8d45ba5db95071ed3889ed1412929f33610636c072a4b5ab550211",
        "3": 5
    }
}

but don't forget to remove --json-metadata-detailed-schema in this case

@gitmachtl
Copy link
Contributor

gitmachtl commented May 22, 2023

I wanna suggest an interesting idea for future SPO polls or any other things that needs an identification of an SPO. We talked about to sign messages with the VRF key in the past, and there were pros and cons about this. A few of us suggested to use a separate "registered" ed25519 voting key as a "stand in" to represent the SPO.

The current poll issue with the pool cold key on the hw wallet got me thinking, and i think a wonderful solution would be to simply let the SPOs do a PoolUpdate-Registration with metadata attached. This metadata contains the voting key (or lets call it a representation key) - similar generated than CIP36. That way we have a proof on chain that the SPO is in charge of the right pool secret key, and we also have an association of that SPO/Pool to a normal ed25519 key. No VRF signing required. And it can be done by both, cli pool keys and by hw pool keys. I already tested the hw pool key side.

Thoughts?

@gitmachtl
Copy link
Contributor

I could write up a draft for a "Pool Authentication" CIP using such a metadata method. There could also be more information in it. Also would it be possible to combine multiple Pools together under one key if someone likes to do so. Having a standard ed25519 key makes many things easier for signing and without the risk to expose a cold key or the vrf key in the future for every kind of transaction that need such a proof.

@rphair
Copy link
Collaborator

rphair commented Jun 6, 2023

@gufmar @KtorZ what about #516? Should a branch owner fix that merge conflict so we can merge it? 🙃

Copy link
Collaborator

@rphair rphair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The force-push does mess with the timeline a little, but I've read the latest individual commits and I think the last push includes the pending work based on the last SPO poll and the updates about "procedure & duration" with the revised graphic.

As a participant in the poll I think this CIP documents a successful process. Maybe the "second test run" mentioned in the Implementation Plan would be desirable before merging this, but personally I don't think it's required and that what we've seen so far would be enough to merge this as Active (especially since it already is).

I really would, though, like to see the CIP document or at least mention how to include a 674 metadata statement along with the vote, since there was some practical uncertainty in the community about how to do this:

... although it wouldn't strictly be a requirement for this CIP & maybe rather a separate CIP on collating & interpreting poll results.

@KtorZ KtorZ merged commit a79bd1a into master Jun 9, 2023
@KtorZ KtorZ deleted the cip-spo-polls branch June 9, 2023 06:31
@rphair rphair added the CIP-0010: new registry entry Adding a new entry to the metadata label registry label Jun 9, 2023
Ryun1 pushed a commit to Ryun1/CIPs that referenced this pull request Jul 28, 2023
* Draft SPO on-chain voting proposal

Co-authored-by: gufmar

* procedure and duration

describe the ballot cast + redelegation epoch sequence

* update procedure and duration

replace vote/ballot by answer
explain the current definition of answer and delegation durations

* Update CIP-0094_procedure-duration.png

* Draft SPO on-chain voting proposal

Co-authored-by: gufmar

* Update CIP-0094 to active

* Document extra metadata via CIP-0020 (lbl 694) for polls + add entry to CIP-0010

---------

Co-authored-by: Markus <gufmar@gmail.com>
Ryun1 pushed a commit to Ryun1/CIPs that referenced this pull request Nov 17, 2023
* Draft SPO on-chain voting proposal

Co-authored-by: gufmar

* procedure and duration

describe the ballot cast + redelegation epoch sequence

* update procedure and duration

replace vote/ballot by answer
explain the current definition of answer and delegation durations

* Update CIP-0094_procedure-duration.png

* Draft SPO on-chain voting proposal

Co-authored-by: gufmar

* Update CIP-0094 to active

* Document extra metadata via CIP-0020 (lbl 694) for polls + add entry to CIP-0010

---------

Co-authored-by: Markus <gufmar@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Category: Tools Proposals belonging to the 'Tools' category. CIP-0010: new registry entry Adding a new entry to the metadata label registry
Projects
None yet
Development

Successfully merging this pull request may close these issues.