code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/key_rotations.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 type KeyRotations struct { 30 *ConnectionSource 31 } 32 33 var keyRotationsOrdering = TableOrdering{ 34 ColumnOrdering{Name: "vega_time", Sorting: ASC}, 35 ColumnOrdering{Name: "node_id", Sorting: ASC}, 36 ColumnOrdering{Name: "old_pub_key", Sorting: ASC}, 37 ColumnOrdering{Name: "new_pub_key", Sorting: ASC}, 38 } 39 40 func NewKeyRotations(connectionSource *ConnectionSource) *KeyRotations { 41 return &KeyRotations{ 42 ConnectionSource: connectionSource, 43 } 44 } 45 46 func (store *KeyRotations) Upsert(ctx context.Context, kr *entities.KeyRotation) error { 47 defer metrics.StartSQLQuery("KeyRotations", "Upsert")() 48 _, err := store.Exec(ctx, ` 49 INSERT INTO key_rotations(node_id, old_pub_key, new_pub_key, block_height, tx_hash, vega_time) 50 VALUES ($1, $2, $3, $4, $5, $6) 51 ON CONFLICT (node_id, vega_time) DO UPDATE SET 52 old_pub_key = EXCLUDED.old_pub_key, 53 new_pub_key = EXCLUDED.new_pub_key, 54 block_height = EXCLUDED.block_height, 55 tx_hash = EXCLUDED.tx_hash 56 `, kr.NodeID, kr.OldPubKey, kr.NewPubKey, kr.BlockHeight, kr.TxHash, kr.VegaTime) 57 58 // TODO Update node table with new pubkey here? 59 60 return err 61 } 62 63 func (store *KeyRotations) GetAllPubKeyRotations(ctx context.Context, pagination entities.CursorPagination) ([]entities.KeyRotation, entities.PageInfo, error) { 64 defer metrics.StartSQLQuery("KeyRotations", "GetAll")() 65 var pageInfo entities.PageInfo 66 keyRotations := []entities.KeyRotation{} 67 68 var args []interface{} 69 var err error 70 query := `SELECT * FROM key_rotations` 71 query, args, err = PaginateQuery[entities.KeyRotationCursor](query, args, keyRotationsOrdering, pagination) 72 if err != nil { 73 return nil, pageInfo, err 74 } 75 76 if err = pgxscan.Select(ctx, store.ConnectionSource, &keyRotations, query, args...); err != nil { 77 return nil, pageInfo, fmt.Errorf("failed to retrieve key rotations: %w", err) 78 } 79 80 keyRotations, pageInfo = entities.PageEntities[*v2.KeyRotationEdge](keyRotations, pagination) 81 82 return keyRotations, pageInfo, nil 83 } 84 85 func (store *KeyRotations) GetByTxHash(ctx context.Context, txHash entities.TxHash) ([]entities.KeyRotation, error) { 86 defer metrics.StartSQLQuery("KeyRotations", "GetByTxHash")() 87 88 var keyRotations []entities.KeyRotation 89 query := `SELECT * FROM key_rotations WHERE tx_hash = $1` 90 91 if err := pgxscan.Select(ctx, store.ConnectionSource, &keyRotations, query, txHash); err != nil { 92 return nil, fmt.Errorf("failed to retrieve key rotations: %w", err) 93 } 94 95 return keyRotations, nil 96 } 97 98 func (store *KeyRotations) GetPubKeyRotationsPerNode(ctx context.Context, nodeID string, pagination entities.CursorPagination) ([]entities.KeyRotation, entities.PageInfo, error) { 99 defer metrics.StartSQLQuery("KeyRotations", "GetPubKeyRotationsPerNode")() 100 var pageInfo entities.PageInfo 101 id := entities.NodeID(nodeID) 102 keyRotations := []entities.KeyRotation{} 103 104 sorting, cmp, cursor := extractPaginationInfo(pagination) 105 106 kc := &entities.KeyRotationCursor{} 107 if err := kc.Parse(cursor); err != nil { 108 return nil, pageInfo, fmt.Errorf("could not parse key rotation cursor: %w", err) 109 } 110 111 cursorParams := []CursorQueryParameter{ 112 NewCursorQueryParameter("vega_time", sorting, cmp, kc.VegaTime), 113 } 114 115 var args []interface{} 116 query := fmt.Sprintf(`SELECT * FROM key_rotations WHERE node_id = %s`, nextBindVar(&args, id)) 117 query, args = orderAndPaginateWithCursor(query, pagination, cursorParams, args...) 118 119 if err := pgxscan.Select(ctx, store.ConnectionSource, &keyRotations, query, args...); err != nil { 120 return nil, pageInfo, fmt.Errorf("failed to retrieve key rotations: %w", err) 121 } 122 123 keyRotations, pageInfo = entities.PageEntities[*v2.KeyRotationEdge](keyRotations, pagination) 124 125 return keyRotations, pageInfo, nil 126 }