code.vegaprotocol.io/vega@v0.79.0/datanode/service/governance.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package service
    17  
    18  import (
    19  	"context"
    20  
    21  	"code.vegaprotocol.io/vega/datanode/entities"
    22  	"code.vegaprotocol.io/vega/datanode/utils"
    23  	"code.vegaprotocol.io/vega/logging"
    24  )
    25  
    26  type ProposalStore interface {
    27  	Add(ctx context.Context, p entities.Proposal) error
    28  	GetByID(ctx context.Context, id string) (entities.Proposal, error)
    29  	GetByIDWithoutBatch(ctx context.Context, id string) (entities.Proposal, error)
    30  	GetByReference(ctx context.Context, ref string) (entities.Proposal, error)
    31  	GetByTxHash(ctx context.Context, txHash entities.TxHash) ([]entities.Proposal, error)
    32  	Get(ctx context.Context, inState *entities.ProposalState, partyIDStr *string, proposalType *entities.ProposalType,
    33  		pagination entities.CursorPagination) ([]entities.Proposal, entities.PageInfo, error)
    34  }
    35  
    36  type VoteStore interface {
    37  	Add(ctx context.Context, v entities.Vote) error
    38  	GetYesVotesForProposal(ctx context.Context, proposalIDStr string) ([]entities.Vote, error)
    39  	GetNoVotesForProposal(ctx context.Context, proposalIDStr string) ([]entities.Vote, error)
    40  	GetByParty(ctx context.Context, partyIDStr string) ([]entities.Vote, error)
    41  	GetByTxHash(ctx context.Context, txHash entities.TxHash) ([]entities.Vote, error)
    42  	GetByPartyConnection(ctx context.Context, partyIDStr string, pagination entities.CursorPagination) ([]entities.Vote, entities.PageInfo, error)
    43  	Get(ctx context.Context, proposalID, partyID *string, value *entities.VoteValue) ([]entities.Vote, error)
    44  	GetConnection(
    45  		ctx context.Context,
    46  		proposalIDStr, partyIDStr *string,
    47  		pagination entities.CursorPagination,
    48  	) ([]entities.Vote, entities.PageInfo, error)
    49  }
    50  
    51  type Governance struct {
    52  	pStore    ProposalStore
    53  	vStore    VoteStore
    54  	pObserver utils.Observer[entities.Proposal]
    55  	vObserver utils.Observer[entities.Vote]
    56  }
    57  
    58  func NewGovernance(pStore ProposalStore, vStore VoteStore, log *logging.Logger) *Governance {
    59  	return &Governance{
    60  		pStore:    pStore,
    61  		vStore:    vStore,
    62  		pObserver: utils.NewObserver[entities.Proposal]("proposal", log, 0, 0),
    63  		vObserver: utils.NewObserver[entities.Vote]("vote", log, 0, 0),
    64  	}
    65  }
    66  
    67  func (g *Governance) AddProposal(ctx context.Context, p entities.Proposal) error {
    68  	err := g.pStore.Add(ctx, p)
    69  	if err != nil {
    70  		return err
    71  	}
    72  	g.pObserver.Notify([]entities.Proposal{p})
    73  	return nil
    74  }
    75  
    76  func (g *Governance) GetProposalByID(ctx context.Context, id string) (entities.Proposal, error) {
    77  	return g.pStore.GetByID(ctx, id)
    78  }
    79  
    80  func (g *Governance) GetProposalByIDWithoutBatch(ctx context.Context, id string) (entities.Proposal, error) {
    81  	return g.pStore.GetByIDWithoutBatch(ctx, id)
    82  }
    83  
    84  func (g *Governance) GetProposalsByTxHash(ctx context.Context, txHash entities.TxHash) ([]entities.Proposal, error) {
    85  	return g.pStore.GetByTxHash(ctx, txHash)
    86  }
    87  
    88  func (g *Governance) GetProposalByReference(ctx context.Context, ref string) (entities.Proposal, error) {
    89  	return g.pStore.GetByReference(ctx, ref)
    90  }
    91  
    92  func (g *Governance) GetProposals(ctx context.Context, inState *entities.ProposalState, partyID *string, proposalType *entities.ProposalType,
    93  	pagination entities.CursorPagination,
    94  ) ([]entities.Proposal, entities.PageInfo, error) {
    95  	return g.pStore.Get(ctx, inState, partyID, proposalType, pagination)
    96  }
    97  
    98  func (g *Governance) ObserveProposals(ctx context.Context, retries int, partyID *string) (<-chan []entities.Proposal, uint64) {
    99  	ch, ref := g.pObserver.Observe(ctx,
   100  		retries,
   101  		func(o entities.Proposal) bool { return partyID == nil || o.PartyID.String() == *partyID })
   102  	return ch, ref
   103  }
   104  
   105  func (g *Governance) AddVote(ctx context.Context, v entities.Vote) error {
   106  	err := g.vStore.Add(ctx, v)
   107  	if err != nil {
   108  		return err
   109  	}
   110  	g.vObserver.Notify([]entities.Vote{v})
   111  	return nil
   112  }
   113  
   114  func (g *Governance) GetYesVotesForProposal(ctx context.Context, proposalID string) ([]entities.Vote, error) {
   115  	return g.vStore.GetYesVotesForProposal(ctx, proposalID)
   116  }
   117  
   118  func (g *Governance) GetNoVotesForProposal(ctx context.Context, proposalID string) ([]entities.Vote, error) {
   119  	return g.vStore.GetNoVotesForProposal(ctx, proposalID)
   120  }
   121  
   122  func (g *Governance) GetVotesByParty(ctx context.Context, partyID string) ([]entities.Vote, error) {
   123  	return g.vStore.GetByParty(ctx, partyID)
   124  }
   125  
   126  func (g *Governance) GetVotesByTxHash(ctx context.Context, txHash entities.TxHash) ([]entities.Vote, error) {
   127  	return g.vStore.GetByTxHash(ctx, txHash)
   128  }
   129  
   130  func (g *Governance) GetByPartyConnection(ctx context.Context, partyID string, pagination entities.CursorPagination) ([]entities.Vote, entities.PageInfo, error) {
   131  	return g.vStore.GetByPartyConnection(ctx, partyID, pagination)
   132  }
   133  
   134  func (g *Governance) GetConnection(
   135  	ctx context.Context,
   136  	proposalID, partyID *string,
   137  	pagination entities.CursorPagination,
   138  ) ([]entities.Vote, entities.PageInfo, error) {
   139  	return g.vStore.GetConnection(ctx, proposalID, partyID, pagination)
   140  }
   141  
   142  func (g *Governance) GetVotes(ctx context.Context, proposalID, partyID *string, value *entities.VoteValue) ([]entities.Vote, error) {
   143  	return g.vStore.Get(ctx, proposalID, partyID, value)
   144  }
   145  
   146  func (g *Governance) ObservePartyVotes(ctx context.Context, retries int, partyID string) (<-chan []entities.Vote, uint64) {
   147  	ch, ref := g.vObserver.Observe(ctx,
   148  		retries,
   149  		func(o entities.Vote) bool { return o.PartyID.String() == partyID })
   150  	return ch, ref
   151  }
   152  
   153  func (g *Governance) ObserveProposalVotes(ctx context.Context, retries int, proposalID string) (<-chan []entities.Vote, uint64) {
   154  	ch, ref := g.vObserver.Observe(ctx,
   155  		retries,
   156  		func(o entities.Vote) bool { return o.PartyID.String() == proposalID })
   157  	return ch, ref
   158  }