code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/parties.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 sqlstore 17 18 import ( 19 "context" 20 "fmt" 21 22 "code.vegaprotocol.io/vega/datanode/entities" 23 "code.vegaprotocol.io/vega/datanode/metrics" 24 v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2" 25 26 "github.com/georgysavva/scany/pgxscan" 27 ) 28 29 var ( 30 partiesOrdering = TableOrdering{ 31 ColumnOrdering{Name: "vega_time", Sorting: ASC}, 32 ColumnOrdering{Name: "id", Sorting: ASC}, 33 } 34 35 partiesProfilesOrdering = TableOrdering{ 36 ColumnOrdering{Name: "id", Sorting: ASC}, 37 } 38 ) 39 40 type Parties struct { 41 *ConnectionSource 42 } 43 44 func NewParties(connectionSource *ConnectionSource) *Parties { 45 ps := &Parties{ 46 ConnectionSource: connectionSource, 47 } 48 return ps 49 } 50 51 // Initialise adds the built-in 'network' party which is never explicitly sent on the event 52 // bus, but nonetheless is necessary. 53 func (ps *Parties) Initialise(ctx context.Context) { 54 defer metrics.StartSQLQuery("Parties", "Initialise")() 55 _, err := ps.Exec(ctx, 56 `INSERT INTO parties(id, tx_hash, alias) VALUES ($1, $2, $3) ON CONFLICT (id) DO NOTHING`, 57 entities.PartyID("network"), entities.TxHash("01"), "network") 58 if err != nil { 59 panic(fmt.Errorf("unable to add built-in network party: %w", err)) 60 } 61 } 62 63 func (ps *Parties) Add(ctx context.Context, p entities.Party) error { 64 defer metrics.StartSQLQuery("Parties", "Add")() 65 _, err := ps.Exec(ctx, 66 `INSERT INTO parties(id, tx_hash, vega_time) 67 VALUES ($1, $2, $3) 68 ON CONFLICT (id) DO NOTHING`, 69 p.ID, 70 p.TxHash, 71 p.VegaTime, 72 ) 73 return err 74 } 75 76 func (ps *Parties) UpdateProfile(ctx context.Context, p *entities.PartyProfile) error { 77 defer metrics.StartSQLQuery("Parties", "Add")() 78 _, err := ps.Exec(ctx, 79 `UPDATE parties SET alias = $1, metadata = $2 WHERE id = $3`, 80 p.Alias, 81 p.Metadata, 82 p.PartyID, 83 ) 84 return err 85 } 86 87 func (ps *Parties) ListProfiles(ctx context.Context, ids []string, pagination entities.CursorPagination) ([]entities.PartyProfile, entities.PageInfo, error) { 88 defer metrics.StartSQLQuery("Parties", "ListProfiles")() 89 90 profiles := make([]entities.PartyProfile, 0) 91 args := make([]interface{}, 0) 92 93 whereClause := "" 94 if len(ids) > 0 { 95 partyIDs := make([][]byte, len(ids)) 96 for i, id := range ids { 97 partyID := entities.PartyID(id) 98 partyIDBytes, err := partyID.Bytes() 99 if err != nil { 100 return nil, entities.PageInfo{}, fmt.Errorf("invalid party ID found: %w", err) 101 } 102 partyIDs[i] = partyIDBytes 103 } 104 whereClause = fmt.Sprintf(" where id = ANY(%s)", nextBindVar(&args, partyIDs)) 105 } 106 107 query := `SELECT id AS party_id, alias, metadata FROM parties` + whereClause 108 109 var pageInfo entities.PageInfo 110 111 query, args, err := PaginateQuery[entities.PartyProfile](query, args, partiesProfilesOrdering, pagination) 112 if err != nil { 113 return nil, pageInfo, err 114 } 115 116 if err := pgxscan.Select(ctx, ps.ConnectionSource, &profiles, query, args...); err != nil { 117 return nil, pageInfo, err 118 } 119 120 profiles, pageInfo = entities.PageEntities[*v2.PartyProfileEdge](profiles, pagination) 121 return profiles, pageInfo, nil 122 } 123 124 func (ps *Parties) GetByID(ctx context.Context, id string) (entities.Party, error) { 125 a := entities.Party{} 126 defer metrics.StartSQLQuery("Parties", "GetByID")() 127 err := pgxscan.Get(ctx, ps.ConnectionSource, &a, 128 `SELECT id, tx_hash, vega_time 129 FROM parties WHERE id=$1`, 130 entities.PartyID(id)) 131 132 return a, ps.wrapE(err) 133 } 134 135 func (ps *Parties) GetByTxHash(ctx context.Context, txHash entities.TxHash) ([]entities.Party, error) { 136 defer metrics.StartSQLQuery("Parties", "GetByTxHash")() 137 138 var parties []entities.Party 139 err := pgxscan.Select(ctx, ps.ConnectionSource, &parties, `SELECT id, tx_hash, vega_time FROM parties WHERE tx_hash=$1`, txHash) 140 if err != nil { 141 return nil, ps.wrapE(err) 142 } 143 144 return parties, nil 145 } 146 147 func (ps *Parties) GetAll(ctx context.Context) ([]entities.Party, error) { 148 parties := []entities.Party{} 149 defer metrics.StartSQLQuery("Parties", "GetAll")() 150 err := pgxscan.Select(ctx, ps.ConnectionSource, &parties, ` 151 SELECT id, tx_hash, vega_time 152 FROM parties`) 153 return parties, err 154 } 155 156 func (ps *Parties) GetAllPaged(ctx context.Context, partyID string, pagination entities.CursorPagination) ([]entities.Party, entities.PageInfo, error) { 157 if partyID != "" { 158 party, err := ps.GetByID(ctx, partyID) 159 if err != nil { 160 return nil, entities.PageInfo{}, err 161 } 162 163 return []entities.Party{party}, entities.PageInfo{ 164 HasNextPage: false, 165 HasPreviousPage: false, 166 StartCursor: party.Cursor().Encode(), 167 EndCursor: party.Cursor().Encode(), 168 }, nil 169 } 170 171 parties := make([]entities.Party, 0) 172 args := make([]interface{}, 0) 173 174 query := ` 175 SELECT id, tx_hash, vega_time 176 FROM parties 177 ` 178 179 var pageInfo entities.PageInfo 180 181 query, args, err := PaginateQuery[entities.Party](query, args, partiesOrdering, pagination) 182 if err != nil { 183 return nil, pageInfo, err 184 } 185 186 if err := pgxscan.Select(ctx, ps.ConnectionSource, &parties, query, args...); err != nil { 187 return nil, pageInfo, err 188 } 189 190 parties, pageInfo = entities.PageEntities[*v2.PartyEdge](parties, pagination) 191 return parties, pageInfo, nil 192 }