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

[API]: Batch Governance Proposal APIs #10069

Closed
7 of 16 tasks
edd opened this issue Nov 14, 2023 · 2 comments · Fixed by #10251
Closed
7 of 16 tasks

[API]: Batch Governance Proposal APIs #10069

edd opened this issue Nov 14, 2023 · 2 comments · Fixed by #10251

Comments

@edd
Copy link
Contributor

edd commented Nov 14, 2023

API Overview

In order to build support for Batch Governance Proposals in to the Governance site
We will extend the existing API to include batch governance proposals
So that the Governance site can show meaningful data (e.g. pass/fail likelihood) for a batch proposal

tl;dr a batch proposal is an object like any other proposal, except its terms field changes to be an array of terms fields.

Specs

0028-GOVE-Governance#batch-proposals

API request details

  • Updates to ProposalSubmission (GRPC)
  • Update to Get governance data (Data Node: GRPC, REST, GraphQL)
    • GraphQL: Update ProposalChange union to include a batch type
    • GraphQL: A Proposal of type ProposalChange contains an array of ProposalTerms as its terms field
    • REST: terms field of a batch proposal is an array of terms
  • Updates to List governance data (Data Node: GRPC, REST, GraphQL. Block Explorer REST)
    • Update proposalType filter
      • Add Batch Governance Proposal as an optional proposalType filter
      • When filtering for a proposalType, if a batch proposal includes a proposal of that type, it must be included in the result.
  • Block Explorer
    • Ensure block explorer properly decodes batch proposals

Sample API output (fetching a batch by ID)

curl -L -X GET 'https://api.n00.testnet.vega.rocks/api/v2/governance?proposalId=cafecafed432035ae7e623470e6627e89f4913bcb79dc9bb57c409b9b7649cf5' \
-H 'Accept: application/json'

This returns a batch that contains two proposals, a transfer and a freeform governance proposal. One person (the proposer) has voted yes.

{
  "data": {
    "proposal": {
      "id": "cafecafed432035ae7e623470e6627e89f4913bcb79dc9bb57c409b9b7649cf5",
      "reference": "",
      "partyId": "69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7cafecafe",
      "state": "STATE_ENACTED",
      "timestamp": "1699610240697284000",
      "terms": {
        "closingTimestamp": "1699610488",
        "enactmentTimestamp": "1699610548",
        "validationTimestamp": "0",
        "batch": [
          {
            "closingTimestamp": "1699015142",
            "enactmentTimestamp": "1699015142",
            "validationTimestamp": "0",
            "newTransfer": {
              "changes": {
                "sourceType": "ACCOUNT_TYPE_NETWORK_TREASURY",
                "source": "",
                "transferType": "GOVERNANCE_TRANSFER_TYPE_BEST_EFFORT",
                "amount": "3333000000",
                "asset": "8ba0b10971f0c4747746cd01ff05a53ae75ca91eba1d4d050b527910c983e27e",
                "fractionOfBalance": "0.1",
                "destinationType": "ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES",
                "destination": "",
                "recurring": {
                  "startEpoch": "9800",
                  "endEpoch": "9839",
                  "dispatchStrategy": {
                    "assetForMetric": "8ba0b10971f0c4747746cd01ff05a53ae75ca91eba1d4d050b527910c983e27e",
                    "metric": "DISPATCH_METRIC_MAKER_FEES_PAID",
                    "markets": [],
                    "entityScope": "ENTITY_SCOPE_INDIVIDUALS",
                    "individualScope": "INDIVIDUAL_SCOPE_ALL",
                    "teamScope": [],
                    "nTopPerformers": "",
                    "stakingRequirement": "",
                    "notionalTimeWeightedAveragePositionRequirement": "",
                    "windowLength": "1",
                    "lockPeriod": "0",
                    "distributionStrategy": "DISTRIBUTION_STRATEGY_PRO_RATA",
                    "rankTable": []
                  }
                }
              }
            }
          },
          {
            "closingTimestamp": "1684342983",
            "enactmentTimestamp": "0",
            "validationTimestamp": "0",
            "newFreeform": {}
          }
        ]
      },
      "rationale": {
        "description": "(The freeform proposal here is pointless)",
        "title": "Do a transfer, and make it snappy"
      },
      "requiredParticipation": "0.07",
      "requiredMajority": "0.66"
    },
    "yes": [
      {
        "partyId": "69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7cafecafe",
        "value": "VALUE_YES",
        "proposalId": "cafecafed432035ae7e623470e6627e89f4913bcb79dc9bb57c409b9b7649cf5",
        "timestamp": "1699610284537647000",
        "totalGovernanceTokenBalance": "50000001000000000000000000",
        "totalGovernanceTokenWeight": "1",
        "totalEquityLikeShareWeight": "0"
      }
    ],
    "no": [],
    "yesParty": {},
    "noParty": {}
  }
}

API test scenarios

Submitting a proposal

  • See linked spec for acceptance criteria

On the list API batches count as both their own type and the type of each of the proposals they contain

GIVEN there are two proposals

  • And the first proposal proposal is a batch, and that batch contains a New Market proposal and a Network Parameter Update proposal
  • And the second proposal is a New Market proposal

WHEN I use GraphQL to list all proposals, filtered by TYPE_NEW_MARKET proposals
THEN the list of results will include two proposals: the batch, and the new market proposal

GIVEN there are two proposals

  • And the first proposal proposal is a batch, and that batch contains a New Market proposal and a Network Parameter Update proposal
  • And the second proposal is a New Market proposal

WHEN I use GraphQL to list all proposals, filtered by TYPE_BATCH proposals
THEN the list of results will include one proposals: the batch,

Block explorer can decode a batch proposal transaction

GIVEN there is a batch proposal transaction in block 5
WHEN I use Block Explorer's REST API to fetch block 5
THEN I can see the full batch proposal including all of its contained proposals

Decision log

  • If List Governance Proposals is filtered by (for example) New Market Proposal, it could return an 'unwrapped' market proposal with a new field that indicated it was part of a batch proposal. This would require fewer changes on clients, but add unneccesary complexity on the API side.
  • Filtering by type will allow filtering for just batch proposals. This will be useful for block explorer
  • Filtering by other types will return proposals of that type and batches that contain one or more of the given proposal type. This may be a breaking change for clients (getting new proposal types in queries that used to only return one type).
@edd edd added this to the 🏰 Palazzo Mistero milestone Nov 14, 2023
@gordsport gordsport moved this to Todo in Core Kanban Nov 14, 2023
@karlem karlem moved this from Todo to In Progress in Core Kanban Dec 7, 2023
@karlem
Copy link
Contributor

karlem commented Dec 8, 2023

  • We have decided to add BatchProposalSubmission instead of updating ProposalSubmission. It make more sense because enactment time is separate for each change and closing time is shared by all, also we don't need any extra validation for missing newAsset change, because we just don't include it in the BatchSubmission anymore.
  • I

@karlem
Copy link
Contributor

karlem commented Dec 14, 2023

Suggested implementation:

Extend the GevernanceData by proposal_type and proposals fields. Where proposals will be present when proposal_type is BATCH.

message GovernanceData {
  enum Type {
    TYPE_SINGLE = 0;
    TYPE_BATCH = 1;
  }

  // Governance proposal that is being voted on.
  Proposal proposal = 1;
  // All YES votes in favour of the proposal above.
  repeated Vote yes = 2;
  // All NO votes against the proposal above.
  repeated Vote no = 3;
  // All latest YES votes by party which is guaranteed to be unique,
  // where key (string) is the party ID i.e. public key and
  // value (Vote) is the vote cast by the given party.
  map<string, Vote> yes_party = 4;
  // All latest NO votes by party which is guaranteed to be unique,
  // where key (string) is the party ID i.e. public key and
  // value (Vote) is the vote cast by the given party.
  map<string, Vote> no_party = 5;

  Type proposal_type = 6;
  repeated Proposal proposals = 7;
}

Extend Vote by per_market_equity_like_share_weight which will be present in case of batch market update proposals.

// Governance vote
message Vote {
  // Vote value
  enum Value {
    // Default value, always invalid
    VALUE_UNSPECIFIED = 0;
    // Vote against the proposal
    VALUE_NO = 1;
    // Vote in favour of the proposal
    VALUE_YES = 2;

    // Note: If adding an enum value, add a matching entry in:
    //       - gateway/graphql/helpers_enum.go
    //       - gateway/graphql/schema.graphql (enum VoteValue)
  }

  // Voter's party ID.
  string party_id = 1;
  // Which way the party voted.
  Value value = 2;
  // Proposal ID being voted on.
  string proposal_id = 3;
  // Timestamp in Unix nanoseconds when the vote was acknowledged by the network.
  int64 timestamp = 4;
  // Total number of governance token for the party that cast the vote.
  string total_governance_token_balance = 5;
  // The weight of this vote based on the total number of governance tokens.
  string total_governance_token_weight = 6;
  // The weight of the vote compared to the total amount of equity-like share on the market.
  string total_equity_like_share_weight = 7;

  map<string, string> per_market_equity_like_share_weight = 8;
}

Every proposal that is part of batch will NOT be fetcheble on it's own. When a proposal ID or filter is used for proposal that is part of a batch the whole batch version of the governance data is returned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants